Interview Hot Questions (Palindrome Linked List)

Given  the head node  of a linked list head , please determine whether it is a palindrome linked list.

If a linked list is a palindrome, then the sequence of linked list nodes is the same when viewed from front to back as from back to front.

       A palindrome linked list is similar to a palindrome string, and the order of forward reading and backward reading is the same, so how do we judge whether a linked list is a palindrome linked list?

Today we use a variety of methods and perspectives to think about problems and take you through the mysteries of algorithms

  • stringify comparison

public boolean isPalindrome(ListNode head) {
        if(head==null){
            return false;
        }
        //一般通过StringBuilder进行字符操作
        StringBuilder s1=new StringBuilder();
        StringBuilder s2=new StringBuilder();
       //通过while循环将链表中的节点添加到字符串中
       while(head!=null){
           s1.append(head.val);
           s2.append(head.val);
           head=head.next;
       }
       //将s2进行翻转
       s2.reverse();
       return s1.toString().equals(s2.toString());}

  • the stack

       By maintaining a stack to save the nodes in the linked list, the stack is a first-in, last-out data structure, so that the linked list can be flipped, and then compared with the original linked list, the correct result can be obtained

 

 public boolean isPalindrome(ListNode head) {
        ListNode cur1=head;
        ListNode cur2=head;
        Stack<ListNode> stack=new Stack<>();
        while(cur1!=null){
            stack.add(cur1);
            cur1=cur1.next;
        }
        while(cur2!=null&&!stack.isEmpty()){
            ListNode curNode=stack.pop();
            if(curNode.val!=cur2.val){
                return false;
            }
            cur2=cur2.next;
        }
        return true;
    }

  • Midpoint Flip vs.

 When the linked list is even: When the linked list is odd:

  1.  Find the center point of the linked list through the fast and slow pointers
    public ListNode findMid(ListNode head){
            ListNode fast=head;
            ListNode slow=head;
            //快慢指针,快走两步,慢走一步,最后slow的位置就是链表的中心点
            while(fast.next!=null&&fast.next.next!=null){
                fast=fast.next.next;
                slow=slow.next;
            }
            return slow;
        }
  2. Flip the linked list behind the center point
    public ListNode reverseList(ListNode head){
            if(head==null){
                return head;
            }
            //前驱
            ListNode pre=null;
            //当前节点
            ListNode cur=head;
            //后继
            ListNode next=null;
            while(cur!=null){
             next=cur.next;
             cur.next=pre;
             pre=cur;
             cur=next;
            }
            //返回前驱
            return pre;
        }
  3. Determine whether the first half of the linked list and the second half of the linked list are equal
    public boolean isSame(ListNode l1,ListNode l2){
            ListNode p1=l1;
            ListNode p2=l2;
            //这里只能判断p2,因为p1d的话,它上半段遍历完,它会接着遍历下半段
            while(p2!=null){
                if(p1.val!=p2.val){
                    return false;
                }
                p1=p1.next;
                p2=p2.next;
            }
            return true;
        }

 source code:

public boolean isPalindrome(ListNode head) {
       if(head==null){
           return true;
       }
       ListNode mid=findMid(head);
       ListNode l1=head;
       ListNode l2=mid.next;
       l2=reverseList(l2);
       return isSame(l1,l2);
    }
    public ListNode findMid(ListNode head){
        ListNode fast=head;
        ListNode slow=head;
        while(fast.next!=null&&fast.next.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }

    public ListNode reverseList(ListNode head){
        if(head==null){
            return head;
        }
        ListNode pre=null;
        ListNode cur=head;
        ListNode next=null;
        while(cur!=null){
         next=cur.next;
         cur.next=pre;
         pre=cur;
         cur=next;
        }
        return pre;
    }
    public boolean isSame(ListNode l1,ListNode l2){
        ListNode p1=l1;
        ListNode p2=l2;
        while(p2!=null){
            if(p1.val!=p2.val){
                return false;
            }
            p1=p1.next;
            p2=p2.next;
        }
        return true;
    }

 

  • deque

By maintaining a double-ended queue to operate, the so-called double-ended queue can enter from the end of the queue or from the head of the queue.

 while(head!=null){
          queue.addLast(head);
          head=head.next;
      }

       Put all the elements in the linked list into the double-ended queue. After the end, take the nodes from the head and tail of the queue at the same time to judge whether they are equal (equivalent to reverse double pointers)

          ListNode h=queue.removeFirst();
          ListNode t=queue.removeLast();
          if(h.val!=t.val){
              return false;
          }

 When the number of nodes in the linked list is even:

 

 When the number of nodes in the linked list is even:

 So the end condition of the loop is:

while(queue.size()>1){
    ...
}

  • Recursion (linked lists recursively run towards each other)

 

       Recurse to the last node and return directly, compare with the current node, if they are equal, move the current node back one bit, recurse and return, this can be compared from both sides

private void dfs(ListNode head, ListNode phead, boolean res) {
        if (head == null || !res) {
            return;
        }
        dfs(head.next, phead, res);
        if (head.val != phead.val) {
            res = false;
        }
        phead = phead.next;  
    }
    public boolean isPalindrome(ListNode head) {
        boolean res = true;
        ListNode phead = head;
        dfs(head, phead, res);
        return res;
    }

Do you think there is something wrong with this code?

       The test results are all true, indicating that our process has not changed the default value of our res, because our java is passed by value, not by reference, so it will not change our value, so we need to pass res, traversal Nodes are encapsulated into an object for transfer

 private void dfs(ListNode head, ListNode[] phead, boolean[] res) {
        if (head == null || !res[0]) {
            return;
        }
        dfs(head.next, phead, res);
        if (head.val != phead[0].val) {
            res[0] = false;
        }
        phead[0] = phead[0].next;
    }

    public boolean isPalindrome(ListNode head) {
        boolean[] res = {true};
        ListNode[] phead = {head};
        dfs(head, phead, res);
        return res[0];
    }

       All these methods have been introduced. I hope that when you do the problem, don’t just remember one solution to solve the problem, think more about other methods, broaden your thinking, and not be limited to one solution.

Guess you like

Origin blog.csdn.net/dfdbb6b/article/details/132265934