*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; 
    }
}

 

posted @ 2018-08-05 10:48  wz30  阅读(211)  评论(0编辑  收藏  举报