Skip to content

Commit a4d6786

Browse files
authored
Merge pull request #8 from programmingbookclub/meetup-19
LeetCode 讀書會第 19 次聚會 2021/01/12
2 parents 72fe43d + ee879ef commit a4d6786

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# LeetCode 讀書會第 19 次聚會 2021/01/12
2+
3+
leetcode 讀書會通知
4+
1. 項目: 第 19 次聚會
5+
2. 目的: 線上一起寫題目, 由有想法的人帶領, 先解題, 再看該題有趣的解法
6+
3. 時間: 01/12 (二) 20:00 ~ 21:00
7+
4. 地點: google meet 線上 (前 10 分鐘預備鏈接)
8+
5. 解題項目: [Linked list - classic problem 的最後一題 Remove Nth Node From End Of List](https://leetcode.com/explore/learn/card/linked-list/219/classic-problems/)
9+
10+
6. 共筆: GitHub https://github.com/programmingbookclub/Leetcode-club
11+
12+
通知 9 人: @游諭, @turtle, @james, @Louis, @TzuHsuan
13+
14+
備註: 這次的題目是:
15+
16+
17+
1. 203 - easy: Remove Linked List Elements
18+
2. 328 - Medium: Odd Even Linked List
19+
3. 234 - easy:Palindrome Linked List
20+
21+
22+
請在 issue 回報一下,我會把你加入 contribution
23+
24+
https://zh.wikipedia.org/wiki/差一错误
25+
26+
# Remove Linked List Elements
27+
28+
```swift
29+
// swift
30+
func removeElements(_ head: ListNode?, _ val: Int) -> ListNode? {
31+
let dummy = ListNode(0, head)
32+
var prev: ListNode? = dummy
33+
var current: ListNode? = head
34+
35+
while(current != nil) {
36+
if current?.val == val { // 檢查 val
37+
prev?.next = current?.next
38+
} else {
39+
prev = current // 更新 prev
40+
}
41+
current = current?.next // 往後走
42+
}
43+
return dummy.next
44+
}
45+
```
46+
47+
```swift
48+
// swift
49+
/**
50+
* Definition for singly-linked list.
51+
* public class ListNode {
52+
* public var val: Int
53+
* public var next: ListNode?
54+
* public init() { self.val = 0; self.next = nil; }
55+
* public init(_ val: Int) { self.val = val; self.next = nil; }
56+
* public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
57+
* }
58+
*/
59+
class Solution {
60+
func removeElements(_ head: ListNode?, _ val: Int) -> ListNode? {
61+
let dummy = ListNode(val &+ 1, head)
62+
var current: ListNode? = dummy
63+
64+
while(current != nil) {
65+
66+
if current?.next?.val == val { // 檢查 val
67+
current?.next = current?.next?.next
68+
} else {
69+
current = current?.next // 往後走
70+
}
71+
}
72+
return dummy.next
73+
}
74+
}
75+
```
76+
77+
# Odd Even Linked List
78+
79+
80+
# Palindrome Linked List
81+
82+
## Recursive
83+
84+
```swift=
85+
// swift
86+
/**
87+
* Definition for singly-linked list.
88+
* public class ListNode {
89+
* public var val: Int
90+
* public var next: ListNode?
91+
* public init() { self.val = 0; self.next = nil; }
92+
* public init(_ val: Int) { self.val = val; self.next = nil; }
93+
* public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
94+
* }
95+
*/
96+
class Solution {
97+
/*
98+
99+
1
100+
11
101+
121 2 11
102+
1221 22 11
103+
1231 23 11
104+
*/
105+
func isPalindrome(_ head: ListNode?) -> Bool {
106+
var ptr: ListNode? = head
107+
func helper(_ head: ListNode?) -> Bool {
108+
if head == nil {return true}
109+
if helper(head?.next) == false {return false}
110+
if (head?.val != ptr?.val) {return false}
111+
ptr = ptr?.next
112+
return true
113+
}
114+
115+
return helper(head)
116+
}
117+
}
118+
```
119+
120+
## Iterative & in-place
121+
122+
遍歷整個 List 3 次
123+
1. 計算長度
124+
2. 反轉後半段
125+
3. Two pointer 從兩端檢查是否相同
126+
127+
```typescript=
128+
// TypeScript
129+
130+
/**
131+
Iterative & in-place
132+
time: O(3n) = O(n), space: O(1)
133+
*/
134+
function isPalindrome(head: ListNode | null): boolean {
135+
// 算出長度
136+
const length = getListLength(head);
137+
if (length <= 1) return true;
138+
// 反轉後半段,並額外考慮長度為偶數的情況
139+
const middleNode = getNthNode(head, Math.ceil(length / 2));
140+
const anotherHead = length % 2 === 0 ? reverseList(middleNode.next) : reverseList(middleNode);
141+
middleNode.next = null;
142+
// Two pointer 從兩端檢查是否相同
143+
return isSameList(head, anotherHead);
144+
};
145+
146+
// 以下為輔助函式
147+
function isSameList(headA: ListNode, headB: ListNode): boolean {
148+
let currA = headA;
149+
let currB = headB;
150+
while(currA != null) {
151+
if (currA.val !== currB.val) return false;
152+
currA = currA.next;
153+
currB = currB.next;
154+
}
155+
if (currB == null) return true;
156+
else return false;
157+
}
158+
159+
function getListLength(head: ListNode): number {
160+
let count = 0;
161+
let curr = head;
162+
while(curr != null) {
163+
count++;
164+
curr = curr.next;
165+
}
166+
return count;
167+
}
168+
169+
function getNthNode(head: ListNode, n: number): ListNode {
170+
if (head == null || !Number.isInteger(n) || n < 1) return null;
171+
let count = 1;
172+
let curr = head;
173+
while(count < n) {
174+
curr = curr?.next;
175+
count++;
176+
}
177+
return curr;
178+
}
179+
180+
/** Iteratively */
181+
function reverseList(head: ListNode | null): ListNode | null {
182+
if (!head) return null;
183+
let curr = head;
184+
let prev: ListNode = null;
185+
let next: ListNode = null;
186+
while(curr) {
187+
next = curr.next ?? null;
188+
curr.next = prev;
189+
prev = curr;
190+
curr = next;
191+
}
192+
return prev;
193+
};
194+
```
195+
196+
197+
198+
![](https://i.imgur.com/UJSIGtG.png)
199+
200+
比較了 Recursive vs Iterative
201+
202+
Runtime: 92 vs 100 ms
203+
204+
Memory: 45.7 vs 42.3 MB
205+

0 commit comments

Comments
 (0)