【详细整理】234. 回文链表

276 阅读1分钟

题目

leetcode-cn.com/problems/pa… 请判断一个链表是否为回文链表。就是前一半和后一半是否相等

思路1——双指针

用快慢指针找到中点,然后反转后半部分,然后再和前半部分比较是否一样。

快慢指针找中点:快指针一次走两步,慢指针一次一步,快指针null的时候,慢指针刚好到中点

1、奇数时:刚好中间,偶数:在中间偏后一个位置。所以后链表要不比前链表多一个元素,要不一样长,所以比较的限制是while(前链表==null)

这里思路错了,应该是head和slow对比,所以head元素是比slow多的,那就是slow==null(这里又有一个问题,slow、fast会对原链表进行修改吗,调试告诉我,不会。)

代码1

    public boolean isPalindrome(ListNode head) {
        ListNode fast = head,slow=head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        slow = reverse(slow);
        fast = head;
        while(slow != null){
            if(fast.val != slow.val){
                return false;
            }
            slow = slow.next;
            fast =  fast.next;
            
        }
        return true;
    }
    public ListNode reverse(ListNode slow){
        ListNode a = slow,b = null;
        while(a != null){
            ListNode temp = a.next;
            a.next = b;
            b = a;
            a = temp;
            
        }
        return b;

    }
}

思路2——栈

栈先入后出,所以可以后半部分出栈比较,具体应该就是: 链表入栈,记录长度,1/2元素出栈进行比较。

    public boolean isPalindrome(ListNode head) {
        if(head == null){
            return true;
        }
        Stack<Integer> s = new Stack();
        int L = 0;
        ListNode temp = head;
        while(temp != null){
            s.push(temp.val);
            temp = temp.next;
            L++;
        }
        L = L >>= 1;
        
        // 开始这样写一直报错,发现终止条件是运算,每次都会执行,所以L的值也就每次改变了
        // for(int i = 0;i <= (L >>= 1);i++){
        
        for(int i = 0;i <= L;i++){
            if(head.val != s.pop()){
                return false;
            }
            head = head.next;
        }
        return true;


    }
}