*Amazon problem: 234. Palindrome Linked List (reverse the linked list with n time)
Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2 Output: false
Example 2:
Input: 1->2->2->1 Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
Sloving with O(3n) -> O(n)
Idea: reversing the list and match
probelm 1: how to find the middle node of list:
//1: find the middle node : slow and fast ListNode slow = head; ListNode fast = head; while(fast !=null && fast.next!= null){// fast could be null(odd list) or last node (even list) fast = fast.next.next; slow = slow.next; } if(fast != null){ // odd node slow = slow.next; }
problem 2: how to reverse the list
//output slow as head node of second half list //reverse the second half list ListNode end = null, temp; //end: end of second hald list, temp while(slow != null){ temp = slow.next; slow.next = end; //temp.next = slow; end = slow; slow = temp; } slow = end; //take end as a start of 2nd list
last code snippest: compare the two part until the 2nd is null
while(slow!=null){ if(slow.val == head.val){ slow = slow.next; head = head.next; //System.out.println("iside loop:"+slow.val); } else return false; } return true;
Toatlly:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public boolean isPalindrome(ListNode head) {//head means the first node //boundary case: if(head == null || head.next==null) return true; if(head.next.next==null) return head.val==head.next.val; //reverse the half list and compare //1: find the middle node : slow and fast ListNode slow = head; ListNode fast = head; while(fast !=null && fast.next!= null){// fast could be null or last node fast = fast.next.next; slow = slow.next; } if(fast != null){ // odd node slow = slow.next; } System.out.println(slow.val); //output slow as head node of second half list //reverse the second half list ListNode end = null, temp; //end: end of second hald list, temp while(slow != null){ temp = slow.next; slow.next = end; //temp.next = slow; end = slow; slow = temp; } slow = end; System.out.println(slow.val); //slow id the start node of the 2nd list while(slow!=null){ if(slow.val == head.val){ slow = slow.next; head = head.next; //System.out.println("iside loop:"+slow.val); } else return false; } return true; //compare,input: head and tail } }
In the linkedlist, know the diff between temp.next = slow | temp = slow(temp(as a pointer) point to slow)
Also reference is https://blog.csdn.net/liuchonge/article/details/73658088
If you could slove this problem: you cna simply slove 206. Reverse Linked List iteratively
However, the recursive(1 hour to undderstand) way is tricky. Here is good reference https://www.geeksforgeeks.org/reverse-a-linked-list/ (with clear picture)
1) Divide the list in two parts - first node and rest of the linked list. 2) Call reverse for the rest of the linked list. 3) Link rest to first. 4) Fix head pointer
recusrive way: go deep firstly and then reverse :
head.next.next = head;
head.next = null;
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseList(ListNode head) { if(head == null || head.next==null){ return head;//last node } ListNode res = reverseList(head.next);//go deep firstly head.next.next = head; head.next = null; return res; } }