java determines whether a single linked list is a palindrome linked list

Keywords: Java Programming Algorithm data structure linked list

To judge whether a linked list is a palindrome linked list, you can use the stack or the speed pointer
These are the codes sorted out according to Zuo Chengyun's algorithm course

1. With the help of stack structure, the feature of first in and last out

Traverse the linked list and put it on the stack at one time, then traverse the linked list again and pop up the stack for comparison in turn. If it is identical, it means it is a palindrome linked list. If it is different, it is not

private static boolean isPalindrome(Node head){
    Stack<Node> stack = new Stack<>();
    Node cur = head;//Make a copy of the linked list
    //Traverse the linked list and put it on the stack
    while (null != cur){
        stack.push(cur);
        cur = cur.next;
    }
	
	//Traverse the linked list and exit for comparison in turn
    while (null != head){
        if (head.value != stack.pop().value){
            return false;
        }
        head = head.next;
    }
    return true;
}

2. Still use the stack while using the fast and slow pointers

Use the speed pointer to get the middle position of the linked list, and put the latter half of the linked list on the stack in turn. Similarly, use the first in then out feature to traverse the linked list again and out of the stack in turn. If the stack is empty, it is the palindrome linked list.
In the java language, there is no concept of pointer. The fast and slow pointer here controls the speed of traversing the linked list. When traversing the linked list, two variables are prepared for traversal at the same time. One variable traverses one node at a time and one variable traverses two nodes at a time, as shown below:

public static class Node{
    private int value;
    private Node next;

    public Node(int value) {
        this.value = value;
    }
}

public static void test(Node head){
	node1 = head;
	node2 = head;
	while(node2.next != null && node2.next.next != null){
		node1 = node1.next;//Traverse one node at a time
		node2 = node2.next.next;//Traverse 2 nodes at a time
	}
}

When there is only one node or no node behind node2, it ends. At this time, node2 has no nodes to traverse. At this time, node1 is in the middle position, and the node behind node1 is just the second half of the whole linked list. This method of finding the middle position of the linked list is called speed pointer.
The specific implementation code for judging palindromes is as follows

private static boolean isPalindrome(Node head){
   if (null == head || null == head.next){
       return true;
   }
   Stack<Node> stack = new Stack<>();
   Node right = head.next;//Slow pointer
   Node cur = head;//Quick pointer
	//Using fast and slow pointers to obtain intermediate nodes
   while (cur.next != null && cur.next.next != null){
       right = right.next;
       cur = cur.next.next;
   }
   //Right half node stack
   while (null != right){
       stack.push(right);
       right = right.next;
   }
   //Out of the stack, compared with the original linked list traversal
   while (!stack.isEmpty()){
       if (head.value != stack.pop().value){
           return false;
       }
       head = head.next;
   }
   return true;
}

This method mainly makes use of the characteristics of palindrome linked list. The data of the first half of the linked list is the same as that of the second half, so just flip the second half of the linked list and compare it with the first half of the linked list.

This method has one more variable than the previous linked list, but the variables on the stack are half less and the additional space is half less

3. Without stack, use the linked list variable to flip the linked list for judgment

Use the speed pointer to get the middle position of the linked list, take the linked list on the right half and flip it. Use the characteristics of the palindrome linked list to traverse the original linked list and the inverted linked list on the right half at the same time. For a comparison, if it is completely consistent, it is the palindrome linked list. The code here is a little difficult to understand. It's not as easy as the first two. However, if you understand the single linked list turnover, it's easy to understand. For those who don't understand the single linked list turnover, you can search the information on the Internet or directly look at my code about the single linked list and double linked list turnover
java reverse single linked list and double linked list

private static boolean isPalindrome3(Node head){
    Node n1 = head;
    Node n2 = head;

    //Speed the pointer to get the middle position of the linked list
    while (n2.next != null && n2.next.next != null){
        n1 = n1.next;
        n2 = n2.next.next;
    }
    n2 = n1.next;
    n1.next = null;
    Node n3;
    //Take the right half of the list and flip it
    while (null != n2){
        n3 = n2.next;
        n2.next = n1;
        n1 = n2;
        n2 = n3;
    }
    n2 = head;
    n3 = n1;
    //Traverse the original linked list and the overturned linked list, and compare them in turn
    while (n1 != null && n2 != null){
    	//If you have different values, it means that it is not a palindrome linked list
        if (n1.value != n2.value){
            return false;
        }
        n1 = n1.next;
        n2 = n2.next;
    }
    return true;
}

Summary:

The first method is the simplest and quickest, which is best understood. Using the characteristics of the stack, first in and then out, is equivalent to flipping the linked list and comparing it with the original linked list, but it requires more additional space, and the additional space to be borrowed is O(n),
The second method is slightly improved because the linked list with only half of the stack is compared with the original linked list. The extra space needed is only half that of mode 1.
The code of the third method is difficult to understand, but the idea is very simple. Take the last half of the linked list and flip it. Compare it with the original linked list. If there are different node values, it is not a palindrome linked list. This makes use of the characteristics of palindromes. Without the help of stack, it only uses a few variables. The additional space required is O(1), constant level. The code of the third method mainly needs to understand the flip of the linked list. If you understand this, you can easily understand the code of the third method.
The latter two methods are optimized. The optimization principle is based on the characteristics of palindromes. The flip of the right half is completely consistent with that of the left.

Posted by james_kirk on Wed, 13 Oct 2021 10:25:33 -0700