|
1 | 1 | package com.fishercoder.solutions;
|
2 | 2 |
|
3 | 3 | import com.fishercoder.common.classes.ListNode;
|
4 |
| -import com.fishercoder.common.utils.CommonUtils; |
5 | 4 |
|
6 |
| -import java.util.Stack; |
| 5 | +import java.util.ArrayList; |
| 6 | +import java.util.List; |
7 | 7 |
|
8 |
| -/**Given a singly linked list, determine if it is a palindrome. |
| 8 | +/** |
| 9 | + * 234. Palindrome Linked List |
| 10 | + * Given a singly linked list, determine if it is a palindrome. |
9 | 11 |
|
10 | 12 | Follow up:
|
11 |
| - Could you do it in O(n) time and O(1) space?*/ |
| 13 | + Could you do it in O(n) time and O(1) space? |
| 14 | + */ |
| 15 | + |
12 | 16 | public class _234 {
|
13 |
| - //then I turned to Discuss, and found that they actually reverse the half and then do the comparison, e.g. https://discuss.leetcode.com/topic/33376/java-easy-to-understand |
14 |
| - //a strong candidate would try to restore the reversed half before return to keep the input intact |
15 |
| - //practice does make perfect! Cheers! I implemented this code in 20 mins this time! Cheers! |
16 |
| - public boolean isPalindrome_O1_space(ListNode head) { |
17 |
| - if(head == null) return true; |
18 |
| - //how to get to middle node in a list? a typical trick is to use slow/fast pointers, when fast reaches the end, slow arrives at the middle |
19 |
| - ListNode slow = head, fast = head; |
20 |
| - while(fast.next != null && fast.next.next != null){ |
21 |
| - fast = fast.next.next; |
22 |
| - slow = slow.next; |
23 |
| - } |
24 |
| - //if we exit due to fast.next == null, that means the length of this list is odd, |
25 |
| - //if it's due to fast.next.next == null, then it's even |
26 |
| - //actually it doesn't matter whether the length if odd or even, we'll always use slow as the newHead to reverse the second half |
27 |
| - ListNode reversedHead = reverse(slow.next); |
28 |
| - CommonUtils.printList(reversedHead); |
29 |
| - CommonUtils.printList(head); |
30 |
| - ListNode firstHalfHead = head; |
31 |
| - while(firstHalfHead != null && reversedHead != null){ |
32 |
| - if(firstHalfHead.val != reversedHead.val) return false; |
33 |
| - firstHalfHead = firstHalfHead.next; |
34 |
| - reversedHead = reversedHead.next; |
| 17 | + public static class Solution1 { |
| 18 | + /**O(n) time |
| 19 | + * O(1) space |
| 20 | + * */ |
| 21 | + public boolean isPalindrome(ListNode head) { |
| 22 | + if (head == null) return true; |
| 23 | + |
| 24 | + ListNode slow = head, fast = head; |
| 25 | + while (fast.next != null && fast.next.next != null) { |
| 26 | + fast = fast.next.next; |
| 27 | + slow = slow.next; |
| 28 | + } |
| 29 | + |
| 30 | + ListNode reversedHead = reverse(slow.next); |
| 31 | + ListNode firstHalfHead = head; |
| 32 | + while (firstHalfHead != null && reversedHead != null) { |
| 33 | + if (firstHalfHead.val != reversedHead.val) return false; |
| 34 | + firstHalfHead = firstHalfHead.next; |
| 35 | + reversedHead = reversedHead.next; |
| 36 | + } |
| 37 | + return true; |
35 | 38 | }
|
36 |
| - return true; |
37 |
| - } |
38 |
| - |
39 |
| - private ListNode reverse(ListNode head) { |
40 |
| - ListNode pre = null; |
41 |
| - while(head != null){ |
42 |
| - ListNode next = head.next; |
43 |
| - head.next = pre; |
44 |
| - pre = head; |
45 |
| - head = next; |
| 39 | + |
| 40 | + private ListNode reverse(ListNode head) { |
| 41 | + ListNode pre = null; |
| 42 | + while (head != null) { |
| 43 | + ListNode next = head.next; |
| 44 | + head.next = pre; |
| 45 | + pre = head; |
| 46 | + head = next; |
| 47 | + } |
| 48 | + return pre; |
46 | 49 | }
|
47 |
| - return pre; |
48 | 50 | }
|
49 | 51 |
|
50 |
| - //I could only think of solutions that use O(n) space: store half of the nodes values |
51 |
| - //I don't know how Two Pointers technique could achieve O(1) effect |
52 |
| - public boolean isPalindrome(ListNode head) { |
53 |
| - //let's get it AC'ed first |
54 |
| - //truely, I got this one AC'ed the first time I submitted it, cheers! |
55 |
| - |
56 |
| - //get the length of the list first |
57 |
| - ListNode temp = head; |
58 |
| - int count = 0; |
59 |
| - while(temp != null){ |
60 |
| - count++; |
61 |
| - temp = temp.next; |
62 |
| - } |
63 |
| - boolean lengthIsEven = (count%2 == 0); |
64 |
| - Stack<Integer> stack = new Stack(); |
65 |
| - temp = head; |
66 |
| - for(int i = 0; i < count/2; i++){ |
67 |
| - stack.push(temp.val); |
68 |
| - temp = temp.next; |
| 52 | + public static class Solution2 { |
| 53 | + /**O(n) time |
| 54 | + * O(n) space |
| 55 | + * */ |
| 56 | + public boolean isPalindrome(ListNode head) { |
| 57 | + int len = 0; |
| 58 | + ListNode fast = head; |
| 59 | + ListNode slow = head; |
| 60 | + List<Integer> firstHalf = new ArrayList<>(); |
| 61 | + while (fast != null && fast.next != null) { |
| 62 | + fast = fast.next.next; |
| 63 | + firstHalf.add(slow.val); |
| 64 | + slow = slow.next; |
| 65 | + len += 2; |
| 66 | + } |
| 67 | + if (fast != null) { |
| 68 | + len++; |
| 69 | + } |
| 70 | + if (len % 2 != 0) { |
| 71 | + slow = slow.next; |
| 72 | + } |
| 73 | + int i = firstHalf.size() - 1; |
| 74 | + while (slow != null) { |
| 75 | + if (firstHalf.get(i--) != slow.val) { |
| 76 | + return false; |
| 77 | + } |
| 78 | + slow = slow.next; |
| 79 | + } |
| 80 | + return true; |
69 | 81 | }
|
70 |
| - |
71 |
| - if(!lengthIsEven) temp = temp.next; |
72 |
| - while(!stack.isEmpty()){ |
73 |
| - if(stack.pop() != temp.val) return false; |
74 |
| - temp = temp.next; |
75 |
| - } |
76 |
| - return true; |
77 |
| - } |
78 |
| - |
79 |
| - public static void main(String...strings){ |
80 |
| - _234 test = new _234(); |
81 |
| -// ListNode head = new ListNode(1); |
82 |
| -// head.next = new ListNode(2); |
83 |
| -// head.next.next = new ListNode(3); |
84 |
| -// head.next.next.next = new ListNode(4); |
85 |
| -// head.next.next.next.next = new ListNode(5); |
86 |
| - |
87 |
| - ListNode head = new ListNode(1); |
88 |
| - CommonUtils.printList(head); |
89 |
| -// ListNode result = test.reverseList_iterative(head); |
90 |
| -// Boolean result = test.isPalindrome(head); |
91 |
| - Boolean result = test.isPalindrome_O1_space(head); |
92 |
| - System.out.println(result); |
93 | 82 | }
|
94 | 83 |
|
95 | 84 | }
|
0 commit comments