Skip to content

Commit 574de55

Browse files
author
Michael Ho
committed
Added new solutions
1 parent 4cb61c2 commit 574de55

File tree

7 files changed

+245
-16
lines changed

7 files changed

+245
-16
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>
Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// LeetCode: https://leetcode.com/problems/merge-k-sorted-lists/description/
22

3+
import XCTest
4+
35
public class ListNode {
46
public var val: Int
57
public var next: ListNode?
@@ -11,33 +13,65 @@ public class ListNode {
1113

1214
class Solution {
1315
func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
14-
var arr: [Int] = []
16+
var arr = [Int]()
17+
1518
for head in lists {
16-
arr = arr + toArray(head)
19+
var node = head
20+
while node != nil {
21+
arr.append((node?.val)!)
22+
node = node?.next
23+
}
1724
}
1825
arr = arr.sorted()
19-
return toLinkedList(arr: arr)
26+
return toLinkedList(arr)
2027
}
21-
private func toArray(_ head: ListNode?) -> [Int] {
22-
guard nil != head else {
23-
return []
24-
}
25-
var arr: [Int] = []
26-
var node = head
27-
while nil != node {
28-
arr.append((node?.val)!)
28+
29+
private func toLinkedList(_ arr: [Int]) -> ListNode? {
30+
guard arr.count > 0 else {
31+
return nil
32+
}
33+
guard arr.count > 1 else {
34+
return ListNode(arr[0])
35+
}
36+
let head = ListNode(arr[0])
37+
var node: ListNode? = ListNode(arr[1])
38+
head.next = node
39+
var index = 1
40+
while index + 1 < arr.count {
41+
node?.next = ListNode(arr[index+1])
2942
node = node?.next
43+
index += 1
3044
}
31-
return arr
45+
return head
3246
}
33-
private func toLinkedList(arr: [Int]) -> ListNode? {
47+
}
48+
49+
class Tests: XCTestCase {
50+
let s = Solution()
51+
52+
func testSample1() {
53+
let input: [ListNode?] = [
54+
arrayToLinkedList([1,4,5]),
55+
arrayToLinkedList([1,3,4]),
56+
arrayToLinkedList([2,6])
57+
]
58+
var output = s.mergeKLists(input)
59+
var expected = arrayToLinkedList([1,1,2,3,4,4,5,6])
60+
while expected != nil {
61+
XCTAssertEqual(expected?.val, output?.val)
62+
output = expected?.next
63+
expected = expected?.next
64+
}
65+
}
66+
67+
private func arrayToLinkedList(_ arr: [Int]) -> ListNode? {
3468
guard arr.count > 0 else {
3569
return nil
3670
}
3771
guard arr.count > 1 else {
3872
return ListNode(arr[0])
3973
}
40-
var head = ListNode(arr[0])
74+
let head = ListNode(arr[0])
4175
var node: ListNode? = ListNode(arr[1])
4276
head.next = node
4377
var index = 1
@@ -49,3 +83,5 @@ class Solution {
4983
return head
5084
}
5185
}
86+
87+
Tests.defaultTestSuite.run()
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// LeetCode: https://leetcode.com/problems/lru-cache/
2+
3+
import XCTest
4+
5+
// Use doubly linked list.
6+
class Node {
7+
var val: Int
8+
var key: Int
9+
var pre: Node?
10+
var next: Node?
11+
12+
init(_ key: Int, _ val: Int) {
13+
self.key = key
14+
self.val = val
15+
}
16+
}
17+
18+
class LRU {
19+
var capacity: Int
20+
var dataCount: Int
21+
var map = [Int:Node]()
22+
var head: Node?
23+
var tail: Node?
24+
25+
init(_ capacity: Int) {
26+
self.capacity = capacity
27+
head = Node(-1, -1)
28+
tail = Node(-1, -1)
29+
head?.next = tail
30+
tail?.pre = head
31+
dataCount = 0
32+
}
33+
34+
func get(_ key: Int) -> Int {
35+
if let node = map[key] {
36+
deleteNode(node)
37+
moveToHead(node)
38+
return node.val
39+
} else {
40+
return -1
41+
}
42+
}
43+
44+
private func deleteNode(_ node: Node?) {
45+
node?.pre?.next = node?.next
46+
node?.next?.pre = node?.pre
47+
}
48+
49+
private func moveToHead(_ node: Node?) {
50+
node?.next = head?.next
51+
head?.next?.pre = node
52+
head?.next = node
53+
node?.pre = head
54+
}
55+
56+
func put(_ key: Int, _ val: Int) {
57+
if let existNode = map[key] {
58+
existNode.key = key
59+
existNode.val = val
60+
deleteNode(existNode)
61+
moveToHead(existNode)
62+
} else {
63+
if dataCount == capacity {
64+
if let last = tail?.pre {
65+
map[last.key] = nil
66+
deleteNode(last)
67+
}
68+
dataCount -= 1
69+
}
70+
71+
let node = Node(key, val)
72+
map[key] = node
73+
moveToHead(node)
74+
dataCount += 1
75+
}
76+
}
77+
}
78+
79+
class Tests: XCTestCase {
80+
81+
func test1() {
82+
let cache = LRU(2)
83+
84+
cache.put(1, 1)
85+
cache.put(2, 2)
86+
XCTAssertEqual(cache.get(1), 1)
87+
88+
cache.put(3, 3)
89+
XCTAssertEqual(cache.get(2), -1) // (not found)
90+
91+
cache.put(4, 4)
92+
XCTAssertEqual(cache.get(1), -1) // (not found)
93+
XCTAssertEqual(cache.get(3), 3)
94+
XCTAssertEqual(cache.get(4), 4)
95+
}
96+
97+
func test2() {
98+
let cache = LRU(2)
99+
100+
cache.put(2, 1)
101+
cache.put(1, 1)
102+
cache.put(2, 3)
103+
cache.put(4, 1)
104+
XCTAssertEqual(cache.get(1), -1)
105+
XCTAssertEqual(cache.get(2), 3)
106+
}
107+
}
108+
109+
Tests.defaultTestSuite.run()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// LeetCode: https://leetcode.com/problems/longest-palindromic-substring/
2+
// Hint: moving frame
3+
4+
import XCTest
5+
6+
class Solution {
7+
func longestPalindrome(_ s: String) -> String {
8+
guard s.count > 0 else { return "" }
9+
10+
var length = s.count
11+
var strArr = Array(s)
12+
13+
while length > 0 {
14+
for i in 0...s.count-length {
15+
var left = i
16+
var right = i+length-1
17+
18+
if right >= strArr.count {
19+
break
20+
}
21+
22+
var isPalindrome = true
23+
while left < right {
24+
if strArr[left] != strArr[right] {
25+
isPalindrome = false
26+
break
27+
}
28+
29+
left += 1
30+
right -= 1
31+
}
32+
33+
if isPalindrome {
34+
return String(strArr[i..<i+length])
35+
}
36+
}
37+
length -= 1
38+
}
39+
return String(strArr[0])
40+
}
41+
}
42+
43+
class Tests: XCTestCase {
44+
let s = Solution()
45+
46+
func testSample1() {
47+
let input = "babad"
48+
let expected = "bab"
49+
XCTAssertEqual(s.longestPalindrome(input), expected)
50+
}
51+
52+
func testSample2() {
53+
let input = "cbbd"
54+
let expected = "bb"
55+
XCTAssertEqual(s.longestPalindrome(input), expected)
56+
}
57+
58+
func testSample3() {
59+
let input = "ac"
60+
let expected = "a"
61+
XCTAssertEqual(s.longestPalindrome(input), expected)
62+
}
63+
64+
func testSample4() {
65+
let input = "abcda"
66+
let expected = "a"
67+
XCTAssertEqual(s.longestPalindrome(input), expected)
68+
}
69+
}
70+
71+
Tests.defaultTestSuite.run()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>

Udacity Practices/SortingAlgorithms.playground/Contents.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,14 @@ print("\(mergeSort(testArray))")
7676
- Average: O(nlog(n))
7777
- Worst: O(n^2)
7878
Space:
79-
- O(1)
79+
- Average: O(log(n))
80+
- Worst: O(n)
8081
*/
8182

8283
func quicksort(_ nums: [Int]) -> [Int] {
8384
guard nums.count > 1 else { return nums }
8485

85-
let pivot = nums[nums.count/2]
86+
let pivot = nums[nums.count-1]
8687
let less = nums.filter { $0 < pivot }
8788
let equal = nums.filter { $0 == pivot }
8889
let greater = nums.filter { $0 > pivot }

0 commit comments

Comments
 (0)