返回

从 TypeScript 代码理解回文数和回文链表的奥妙

前端

回文数与回文链表

在数字世界和数据结构中,回文数和回文链表这两个概念经常出现。它们都具有对称性的特点,即从左到右和从右到左读起来都是相同的。

  • 回文数: 一个回文数是指正序和倒序读起来都一样的数字,例如 121、12321、1234321 等。
  • 回文链表: 一个回文链表是指正向和反向遍历都得到相同顺序的链表,例如 (1 -> 2 -> 2 -> 1) 和 (1 -> 2 -> 3 -> 2 -> 1)。

算法实现

回文数算法

判断一个数字是否是回文数,我们可以采用以下步骤:

  1. 将数字转换为字符串。
  2. 将字符串转换为字符数组。
  3. 将字符数组从中间分割成两部分。
  4. 检查两部分的字符是否相等。
function isPalindromeNumber(num: number): boolean {
  const str = num.toString();
  const arr = str.split('');
  const mid = Math.floor(arr.length / 2);
  for (let i = 0; i < mid; i++) {
    if (arr[i] !== arr[arr.length - i - 1]) {
      return false;
    }
  }
  return true;
}

回文链表算法

判断一个链表是否是回文链表,我们可以采用以下步骤:

  1. 将链表分成两部分。
  2. 将其中一部分反转。
  3. 比较两部分的元素是否相等。
class ListNode {
  val: number;
  next: ListNode | null;
  constructor(val: number) {
    this.val = val;
    this.next = null;
  }
}

function isPalindromeLinkedList(head: ListNode | null): boolean {
  if (head === null || head.next === null) {
    return true;
  }

  let slow = head;
  let fast = head;
  while (fast !== null && fast.next !== null) {
    slow = slow.next;
    fast = fast.next.next;
  }

  const reversedHead = reverseLinkedList(slow);
  while (reversedHead !== null) {
    if (head.val !== reversedHead.val) {
      return false;
    }
    head = head.next;
    reversedHead = reversedHead.next;
  }

  return true;
}

function reverseLinkedList(head: ListNode | null): ListNode | null {
  let prev = null;
  let curr = head;
  while (curr !== null) {
    const next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return prev;
}

结论

通过这篇文章,我们了解了回文数和回文链表的概念,并用 TypeScript 代码实现了它们的判断算法。掌握这些算法可以帮助我们解决实际问题,例如判断一个给定的数字是否是回文数,或者判断一个给定的链表是否是回文链表。