Sword finger Offer II 027 Palindrome linked list
Given the head node of a linked list head ,Please judge whether it is a palindrome linked list. If a linked list is a palindrome, the sequence of linked list nodes is the same from front to back and from back to front.
Method 1: copy the value into the array and use the double finger needle method
Summary of the list:
There are two common list implementations, array list and linked list. If we want to store values in the list, its implementation is as follows:
- The bottom layer of the array list uses the array to store values. We can access the values anywhere in the list at O(1) time through the index, which is based on memory addressing.
- The linked list stores objects called nodes. Each node stores a value and a pointer to the next node. It takes O(n) time to access the node of a specific index, because the node at the next location needs to be obtained through the pointer.
Determining whether the array list is palindrome is very simple. We can use the double pointer method to compare the elements at both ends and move to the middle. One pointer moves from the starting point to the middle, and the other pointer moves from the end point to the middle. This requires O(n) time, because the time to access each element is O(1), and there are n elements to access.
However, the same method is not easy to operate on the linked list, because neither forward access nor reverse access is O(1). Copying the value of the linked list to the array list is O(n), so the easiest way is to copy the value of the linked list to the array list, and then use the double finger needle method to judge.
General idea:
1.Copy linked list to array list 2.Use double pointer to judge whether palindrome
Specific implementation:
In the first step, we need to traverse the linked list and copy the values into the trace array currentNode Points to the current node. Add to array per iteration currentNode.val And update currentNode = currentNode.next . When currentNode==null Stop the cycle when. In the second step, we put a pointer at the beginning and a pointer at the end. In each iteration, we judge whether the elements pointed to by the two pointers are the same. If they are different, return false. The same, the opposite. If it is the same, move the two pointers to the middle and continue to judge until the two pointers meet.
/** * Definition for singly-linked list. * 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) { List<Integer> list = new ArrayList<Integer>(); //Traverse the scale and put the values into the array one by one ListNode currnetNode = head; while(currnetNode!=null){ list.add(currnetNode.val); currnetNode=currnetNode.next; } //Set two pointers at both ends of the array int front = 0; int back =list.size()-1; while(front<back){ if(!list.get(front).equals(list.get(back))){ return false; }else{ front++; back--; } } return true; } }
Method 2: recursion
Recursion provides us with an elegant way to traverse nodes in different directions.
function print_values_in_reverse(ListNode head){ if(head!=null){ print_values_in_reverse(head.next); } }
If you use the recursive reverse iteration node and use the variables outside the recursive function to iterate forward, you can judge whether the linked list is a palindrome.
Implementation idea:
currentNode The pointer is the first to last node. Because of the recursive feature, it is compared from back to front. frontPointer Is a pointer outside a recursive function. if currentNode.val != frontPointer.val Then return false. conversely, frontPointer Move forward and back true.
/** * Definition for singly-linked list. * 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 frontPointer; private boolean recursivelyCheck(ListNode currentNode) { if (currentNode != null) { if (!recursivelyCheck(currentNode.next)) { return false; } if (currentNode.val != frontPointer.val) { return false; } frontPointer = frontPointer.next; } return true; } public boolean isPalindrome(ListNode head) { frontPointer = head; return recursivelyCheck(head); } }