给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

 

示例 1:

输入:head = [1,2,2,1]
输出:true

示例 2:

输入:head = [1,2]
输出:false

 

提示:

  • 链表中节点数目在范围[1, 105]
  • 0 <= Node.val <= 9

 

进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

Related Topics
  • 递归
  • 链表
  • 双指针

  • 👍 1106
  • 👎 0
  • 题解

    常规方法,声明一个新的数组,保存每个节点,方便找到中间节点之后从中间节点往前和往后两个放下查找对比,至于之前的有一个类似的查找链表的中间节点的方法,有一篇类似的可以参考LeetCode刷题【876】链表的中间结点,不过这边的双指针方法的话不方便往回查找节点。

    这边分奇偶长度,偶数长度直接和后一位对比,奇数长度中间节点不需要对比,拿中间节点的前一位和后一位开始对比。

    class Solution {
        public boolean isPalindrome(ListNode head) {
            if (head.next == null){
                return true;
            }
            List<ListNode> list = new ArrayList<>();
            while (head!=null){
                list.add(head);
                head = head.next;
            }
            int mid = list.size() >> 1;
            int l,r;
            if (list.size()%2==0){
                l = mid;
                r = mid+1;
            }else{
                l = mid;
                r = mid+2;
            }
            while (l>0){
                if (list.get(l-1).val != list.get(r-1).val){
                    return false;
                }
                l--;
                r++;
            }
            return true;
        }
    }

    而O(n) 时间复杂度和 O(1)的方法,一开始没想出来,直到看了别人的解法,重新再看到题面的说明,每个节点的值在0-9之间才豁然开朗。所以,题面中的每一个信息都至关重要。

    class Solution {
        public boolean isPalindrome(ListNode head) {
            int num1 = 0, num2 = 0, x = 1;
            while (head!=null){
                num1 = num1 * 10 + head.val;
                num2 = x * head.val + num2;
                x *= 10;
                head = head.next;
            }
            return num1 == num2;
        }
    }

    逻辑就是这样,构建两个值,不同的位上代表对应的节点的值,这样构建出来的整数和反向的位构建出来的整数应该值是相等的,则说明是回文链表。

    不过这里的另一个条件,链表长度为10的5次方的话,我也不确定会不会出现越界超出Integer.MAX_VALUE之后恰好和另一个值相等的情况。

    另外一个解法,用栈,将链表的前半段压入栈。从中间节点开始,依次和栈顶节点对比,如果都相同,说明是回文。

    而在用栈的方法1此之前,我也曾经想过,用两个指针,一个从中间节点往后遍历,一个用递归的方法从中间节点往前返回,这两个指针的值进行比较。但是题面中的链表长度为10的5次方使这种方法成为了不可能,这样的递归深度,必然会导致栈溢出。不过其本质思想和用栈来解决是相同的。