-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLCCI0206-PalindromeLinkedList.go
More file actions
151 lines (137 loc) · 3.57 KB
/
LCCI0206-PalindromeLinkedList.go
File metadata and controls
151 lines (137 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
// 面试题 02.06. Palindrome Linked List LCCI
// Implement a function to check if a linked list 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?
import "fmt"
type ListNode struct {
Val int
Next *ListNode
}
// 打印链表
func printListNode(l *ListNode) {
if nil == l {
return
}
for {
if nil == l.Next {
fmt.Print(l.Val)
break
} else {
fmt.Print(l.Val, " -> ")
}
l = l.Next
}
fmt.Println()
}
// 数组创建链表
func makeListNode(arr []int) *ListNode {
if (len(arr) == 0) {
return nil
}
l := len(arr) - 1
head := &ListNode{arr[l], nil}
for i := l - 1; i >= 0; i-- {
n := &ListNode{arr[i], head}
head = n
}
return head
}
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func isPalindrome(head *ListNode) bool {
arr := []int{}
for ; head != nil; head = head.Next { // 遍历链表
arr = append(arr, head.Val)
}
n := len(arr)
for i, v := range arr[:n/2] {
if v != arr[n-i-1] {
return false
}
}
return true
}
// 递归
func isPalindrome1(head *ListNode) bool {
frontPointer := head
var check func(*ListNode) bool
check = func(node *ListNode) bool {
if node != nil {
if !check(node.Next) { return false }
if node.Val != frontPointer.Val { return false }
frontPointer = frontPointer.Next
}
return true
}
return check(head)
}
// 快慢指针
func isPalindrome2(head *ListNode) bool {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
// 原本计划用fast.Next == nil 代表是奇数,但是可能存在fast是nil导致空指针的情况,所以得用fast != nil来表示奇数长度,奇数slow得往下走一步
if fast != nil {
slow = slow.Next
}
reverse := func(head *ListNode) *ListNode {
cur := head
var prev *ListNode
for cur != nil {
next := cur.Next
cur.Next = prev
prev = cur
cur = next
}
// prev会一直往后移动的。所以应该返回prev,你返回head的,head的next是空的
return prev
}
left, right := head, reverse(slow)
for right != nil {
if left.Val != right.Val {
return false
}
left, right = left.Next, right.Next
}
return true
}
func main() {
// Example 1:
// Input: 1 -> 2
// Output: false
list1 := makeListNode([]int{1,2})
printListNode(list1) // 1 -> 2
fmt.Println(isPalindrome(list1)) // false
// Example 2:
// Input: 1->2->2->1
// Output: true
list2 := makeListNode([]int{1,2,2,1})
printListNode(list2) // 1 -> 2 -> 2 -> 1
fmt.Println(isPalindrome(list2)) // true
list11 := makeListNode([]int{1,2})
printListNode(list11) // 1 -> 2
fmt.Println(isPalindrome1(list11)) // false
list12 := makeListNode([]int{1,2,2,1})
printListNode(list12) // 1 -> 2 -> 2 -> 1
fmt.Println(isPalindrome1(list12)) // true
list21 := makeListNode([]int{1,2})
printListNode(list21) // 1 -> 2
fmt.Println(isPalindrome2(list21)) // false
list22 := makeListNode([]int{1,2,2,1})
printListNode(list22) // 1 -> 2 -> 2 -> 1
fmt.Println(isPalindrome2(list22)) // true
}