Force deduction -- > #234. Linked list of palindromes -- > linked list - Simple (double pointer, array list, recursion, speed pointer)

Title Description:

Example 1:

Output: true

Example 2:

Output: false

Tips:
The number of nodes in the linked list is within the range [1, 105]
0 <= Node.val <= 9

Can you use it   O(n) time complexity and O(1) space complexity solve this problem?

I don't think this problem is difficult, but I wrote it and ran it beyond the time range. I can't find out what the problem is. There should be a problem when reversing the linked list. I will continue to align and improve it in the future.
The idea is:
1. Create a new node temph to store the original header node pointer;
2. Create a new node tempt, which is used to preserve the intermediate node when reversing the linked list;
3. Reverse the linked list to get a new linked list with tail as the head node;
4. Move the head backward one by one and the tail forward one by one. Compare the two pairs. If they are equal, continue to compare; If not, false is returned.
The code is as follows:

```/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode() {}
*     ListNode(int val) { this.val = val; }
*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {//Double pointer
ListNode tail=head; //Traverse from the beginning to find the tail node
ListNode tempt=head;//Used to save the intermediate node when reversing the linked list
while(temph!=null){//Reverse linked list, there is a problem with this code! Caught in a loop
tempt=tail;     //The temporary tail pointer retains the tail pointer that occurred after the last reversal
tail=temph.next;//The real tail pointer moves back one bit
tail.next=tempt;//The next node of the tail pointer points to the remaining node
temph=temph.next;//The temporary header pointer traverses one bit backward
}
return false;
}
tail=tail.next;
}
return true;
}
}```

Method 1: copy the value into the array and use the double finger needle method

This is method 1 on the official website. The idea is:
Due to the particularity of the linked list compared with the array, the linked list cannot directly query a value, but needs to be traversed, and can not be searched in reverse order. It can only be searched in one direction, while the array can obtain a value in O(1). Therefore, it is comprehensively considered to use the array list to save the values in the original linked list, and then use double pointers in the array list to move closer one by one at the same time, Compare the values in the array one by one;

be careful:
Due to my lack of attention to the use details of array lists in my daily use, I need to pay attention to the following differences:
1. The creation of array list does not need to have a definite length like array. You can directly list < integer > arrlist = new ArrayList < integer > (); When creating polymorphism, be careful not to lose the second generic;
2. The value obtained from the array list is: arrList.get(i), instead of linkList.val in the usual linked list;
3. The way to get the array length is arrList.size(), instead of arr.length in ordinary arrays.

Execution result: passed
Execution time: 8 ms at all   Java   Beat 40.24% of users in submission
Memory consumption: 50.9 MB in all   Java   Beat 28.78% of users in submission
Pass test case: 85  /  eighty-five

```/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode() {}
*     ListNode(int val) { this.val = val; }
*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {    //Copy the value into the array and use the two finger needle method
List<Integer> arrList=new ArrayList<Integer>();
while(currentNode!=null){   //Pay attention to the current node. Do not habitually use the next node to judge
currentNode=currentNode.next;
}

int left=0;
int right=arrList.size()-1;
while(left<right){
if(!arrList.get(left).equals(arrList.get(right))){//Note the method of obtaining values from array list, which is different from. val
return false;
}
left++;
right--;
}
return true;
}
}```

Method 2: recursion
This is method 2 in the official website. The cleverness and general idea of using recursion are as follows:
When the recursion starts to jump out of the recursion after the last step, it is just like the result of the reversal of the linked list. It is very elegant to compare the beginning and end gradually closer to the middle here! We also define a global variable pointing to the head node outside the method, which is used to compare with the recursive jump out value in the recursive method. In essence, it is performing forward and reverse iterative matching.
Detailed ideas:
1. In the recursive method, first empty the node. If it is empty, it means that it has reached the end of the linked list and returns directly; If it is not empty, it means that the end of the linked list has not been reached, and you still need to continue recursion until the end of the linked list is found;
2. After finding the end, return true and start to jump out of recursion. At this time, directly execute the second if (because recursion starts from this, it also starts to jump out of recursion). if(!true) means that the conditions are not met, directly start to judge the value. If the values are always equal (the recursion will jump out when they are equal) until all recursions jump out, and finally return true, Is palindrome;
3. If two values are not equal when the third if judges whether the values are equal, false is returned here. After that recursion, the second if(!false) satisfies the loop, and all subsequent recursions meet the conditions here. Finally, false is returned, that is, it is not a palindrome.

Execution result: passed
Execution time: 16 ms at all   Java   Defeated 7.92% of users in submission
Memory consumption: 55.4 MB in all   Java   Defeated 12.42% of users in submission
Pass test case: 85  /  eighty-five

```/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode() {}
*     ListNode(int val) { this.val = val; }
*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
private ListNode front; //External global variable, because it is compared with the value returned after recursion

public boolean isPalindrome(ListNode head) {    //Question giving method
return recursivelyCheck(head);  //Call the recursive method, pass in the header pointer and return the final value
}

public boolean recursivelyCheck(ListNode current){
if(current!=null){          //The current node is not empty
//If it is passed to the next node, first judge whether it is empty,
//If it is empty, it means that it has been recursive to the end of the linked list. It returns true -- > if (! True) - > do not execute, and go to the next if
//If it is not empty, continue to call recursively until the last node -- > is found to go to the previous comment
if(!recursivelyCheck(current.next)){
//This recursion also jumps out of recursion. If it is false (next comment) when it jumps out, this if is satisfied, and then it is satisfied here, that is, the recursion finally returns false, not a palindrome
return false;
}
//Judge whether the values are equal. If not, return false, step out of recursion, and finally return false
if(front.val!=current.val){
return false;
}
front=front.next;
}
return true;
}
}```

Method 3: speed pointer
This is method 3 on the official website:
1. Divide the linked list equally: this method uses the slow pointer to walk one node at a time and the fast pointer to walk two nodes at a time. When the next or next point of the fast pointer is null, it indicates that the linked list has been traversed. At this time, the fast pointer has traversed to the end, and the slow pointer is just in the center of the linked list;
2. Reverse and compare: after reversing the second half of the linked list, traverse from front to back from the two linked lists at the same time, compare them one by one, and finally return the obtained results;
3. Restore linked list: generally, the person proposing the comparison does not want his linked list structure to be affected, so he needs to reverse the linked list after the comparison. He only needs to transfer the corresponding segment head node into the method of reversing the linked list again.

Execution result: passed
Execution time: 6 ms at all   Java   Defeated 60.32% of users in submission
Memory consumption: 48.2 MB in all   Java   Beat 82.32% of users in submission
Pass test case: 85  /  eighty-five

```/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode() {}
*     ListNode(int val) { this.val = val; }
*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {//Speed pointer
return true;
}

//Find the tail node of the first half
//Get the inverted linked list of the second half segment, and start the inversion from the next node of the last node of the first half segment
ListNode secondHalfStart = reverseList(firstHalfEnd.next);

//Determine whether it is palindrome
ListNode p2 = secondHalfStart;
boolean result = true;
while (result && p2 != null) {
if (p1.val != p2.val) {
result = false;
}
p1 = p1.next;
p2 = p2.next;
}

//Restore linked list and return results
firstHalfEnd.next=reverseList(secondHalfStart);//The second half of the linked list is reversed by this method
return result;
}

ListNode prev = null;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}

//Realize the fast and slow pointer, and finally return the slow pointer to get the last node of the first half