Algorithm-Determine whether the linked list is a palindrome linked list

Algorithm-Determine whether the linked list is a palindrome linked list

1. Determine whether the linked list is a palindrome linked list

Question source: Leetcode234 , it is an easy question.

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

We know that a singly linked list only has a pointer to the back, so it cannot be traversed from both ends to the middle like an array, but.

Naturally, we can use the nature of the stack to store the linked list, and then pop it and compare it with the original linked list. The space-time complexity is N/N

    /**
     * 用栈性质实现
     * @param head
     * @return
     */
    public boolean isPalindrome(ListNode head){
    
    
        Stack<ListNode> stack=new Stack<>();
        ListNode curr=head;
        while (curr!=null){
    
    
            stack.push(curr);
            curr=curr.next;
        }
        while (head!=null){
    
    
            if(head.val!=stack.pop().val){
    
    
                return false;
            }
            head=head.next;
        }
        return true;
    }

However, interviewers generally won't let us go like this, let us optimize the complexity of time and space. In terms of time complexity, 2*N has been achieved (stacking and popping), and it is impossible to use log(n) optimized by the dichotomy for this problem. Therefore, we can start from the space complexity.

What is the definition of palindrome characters? Symmetry around the midpoint, so we can first find the midpoint of the linked list and divide the linked list into two parts. The two parts are arranged in reverse order, so we can reverse the previous linked list, and then proceed with the next linked list. Compare!

The knowledge involved
1. The problem of linked list reversal is explained in detail in my previous article, so I won’t say more here.
2. Looking for the midpoint of the linked list, the idea is to use the speed pointer, which is also interpreted in the previous article

    /**
     * 解题思路:在找中点的时候对前半部分进行翻转,时空复杂度为n和1
     * @param head
     * @return
     */
    public boolean isPalindrome(ListNode head){
    
    
        if(head==null||head.next==null){
    
    
            return true;
        }
        ListNode quick=head;
        ListNode slow=head;

        ListNode prev=null;
        ListNode curr=head;
        while (quick!=null&&quick.next!=null){
    
    
            ListNode temp=slow.next;
            quick=quick.next.next;
            slow=slow.next;
            curr.next=prev;
            prev=curr;
            curr=temp;
        }
        if(quick!=null){
    
    //奇数个元素,跳过中间节点
            slow=slow.next;
        }
        ListNode frontNode=prev;
        while (frontNode!=null){
    
    
            if(frontNode.val!=slow.val){
    
    
                return false;
            }
            frontNode=frontNode.next;
            slow=slow.next;
        }
        return true;
    }

It is worth noting that in the process of finding the midpoint of the linked list, if the length of the linked list is even, the slow pointer will eventually point to the node behind the midpoint, and the fast pointer will be null. If the length of the linked list is odd, then the slow pointer will eventually point to the middle Therefore, it needs to point to the next node before comparing.

Guess you like

Origin blog.csdn.net/qq_23594799/article/details/106989126