├── .gitignore
├── LICENSE
├── LeetCodeChallenge
├── ChallengeTests
│ ├── Info.plist
│ ├── TestExtensions.swift
│ ├── TestsAprilWeek1.swift
│ ├── TestsAprilWeek2.swift
│ ├── TestsAprilWeek3.swift
│ ├── TestsAprilWeek4.swift
│ ├── TestsAprilWeek5.swift
│ ├── TestsMayWeek1.swift
│ ├── TestsMayWeek2.swift
│ ├── TestsMayWeek3.swift
│ ├── TestsMayWeek4.swift
│ └── TestsMayWeek5.swift
├── LeetCodeChallenge.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── LeetCodeChallenge.xcscheme
└── LeetCodeChallenge
│ ├── AprilWeek1
│ ├── AprilSolDay1.swift
│ ├── AprilSolDay2.swift
│ ├── AprilSolDay3.swift
│ ├── AprilSolDay4.swift
│ ├── AprilSolDay5.swift
│ ├── AprilSolDay6.swift
│ └── AprilSolDay7.swift
│ ├── AprilWeek2
│ ├── AprilSolDay10.swift
│ ├── AprilSolDay11.swift
│ ├── AprilSolDay12.swift
│ ├── AprilSolDay13.swift
│ ├── AprilSolDay14.swift
│ ├── AprilSolDay8.swift
│ └── AprilSolDay9.swift
│ ├── AprilWeek3
│ ├── AprilSolDay15.swift
│ ├── AprilSolDay16.swift
│ ├── AprilSolDay17.swift
│ ├── AprilSolDay18.swift
│ ├── AprilSolDay19.swift
│ ├── AprilSolDay20.swift
│ └── AprilSolDay21.swift
│ ├── AprilWeek4
│ ├── AprilSolDay22.swift
│ ├── AprilSolDay23.swift
│ ├── AprilSolDay24.swift
│ ├── AprilSolDay25.swift
│ ├── AprilSolDay26.swift
│ ├── AprilSolDay27.swift
│ └── AprilSolDay28.swift
│ ├── AprilWeek5
│ ├── SolutionDay29.swift
│ └── SolutionDay30.swift
│ ├── MayWeek1
│ ├── MaySolDay1.swift
│ ├── MaySolDay2.swift
│ ├── MaySolDay3.swift
│ ├── MaySolDay4.swift
│ ├── MaySolDay5.swift
│ ├── MaySolDay6.swift
│ └── MaySolDay7.swift
│ ├── MayWeek2
│ ├── MaySolDay10.swift
│ ├── MaySolDay11.swift
│ ├── MaySolDay12.swift
│ ├── MaySolDay13.swift
│ ├── MaySolDay14.swift
│ ├── MaySolDay8.swift
│ └── MaySolDay9.swift
│ ├── MayWeek3
│ ├── MaySolDay15.swift
│ ├── MaySolDay16.swift
│ ├── MaySolDay17.swift
│ ├── MaySolDay18.swift
│ ├── MaySolDay19.swift
│ ├── MaySolDay20.swift
│ └── MaySolDay21.swift
│ ├── MayWeek4
│ ├── MaySolDay22.swift
│ ├── MaySolDay23.swift
│ ├── MaySolDay24.swift
│ ├── MaySolDay25.swift
│ ├── MaySolDay26.swift
│ ├── MaySolDay27.swift
│ └── MaySolDay28.swift
│ ├── MayWeek5
│ ├── MaySolDay29.swift
│ ├── MaySolDay30.swift
│ └── MaySolDay31.swift
│ ├── Shared
│ ├── DataModels.swift
│ └── Extensions.swift
│ └── main.swift
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | # .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Michael T. Ho
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestExtensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestExtensions.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Array where Element: Collection, Element.Element: Comparable {
12 |
13 | func compareTo2DArrayIgnoreOrder(_ otherArray: [Element]) -> Bool {
14 | guard self.count == otherArray.count else { return false }
15 |
16 | let thisSorted = self.sorted(by: { $0.count > $1.count })
17 | let otherSorted = otherArray.sorted(by: { $0.count > $1.count })
18 |
19 | return thisSorted.elementsEqual(otherSorted) { (subArray, otherSubArray) -> Bool in
20 | subArray.sorted(by: >).elementsEqual(otherSubArray.sorted(by: >))
21 | }
22 | }
23 | }
24 |
25 | extension SinglyListNode {
26 |
27 | func isEqualToLinkedList(_ otherHead: SinglyListNode?) -> Bool {
28 | guard otherHead != nil else {
29 | return false
30 | }
31 |
32 | var otherNode = otherHead
33 | var node: SinglyListNode? = self
34 |
35 | while node != nil {
36 | if otherNode == nil || (node?.val)! != (otherNode?.val)! {
37 | return false
38 | }
39 | otherNode = otherNode?.next
40 | node = node?.next
41 | }
42 |
43 | return true
44 | }
45 | }
46 |
47 | class TestBinaryMatrix: BinaryMatrix {
48 | private var getCallCount = 0
49 |
50 | override init(matrix: [[Int]]) {
51 | super.init(matrix: matrix)
52 | self.getCallCount = 0
53 | }
54 |
55 | override func get(_ x: Int, _ y: Int) -> Int {
56 | if getCallCount == 100 {
57 | assertionFailure("Error. 100 API calls limit reached.")
58 | }
59 |
60 | getCallCount += 1
61 | return super.get(x, y)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsAprilWeek1.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsWeek1.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | // April Edition
12 | class TestsAprilWeek1: XCTestCase {
13 | let sol1 = AprilSolDay1()
14 | let sol2 = AprilSolDay2()
15 | let sol3 = AprilSolDay3()
16 | let sol4 = AprilSolDay4()
17 | let sol5 = AprilSolDay5()
18 | let sol6 = AprilSolDay6()
19 | let sol7 = AprilSolDay7()
20 |
21 | // MARK: - Day 1: Single Number Tests
22 | func testSingleNumber1() {
23 | let input = [2, 2, 1]
24 | let expected = 1
25 | XCTAssertEqual(sol1.singleNumber(input), expected)
26 | }
27 |
28 | func testSingleNumber2() {
29 | let input = [4, 1, 2, 1, 2]
30 | let expected = 4
31 | XCTAssertEqual(sol1.singleNumber(input), expected)
32 | }
33 |
34 | // MARK: - Day 2: Happy Number Tests
35 | func testHappyNumber1() {
36 | let input = 19
37 | /**
38 | 1^2 + 9^2 = 82
39 | 8^2 + 2^2 = 68
40 | 6^2 + 8^2 = 100
41 | 1^2 + 0^2 + 0^2 = 1
42 | */
43 | XCTAssertTrue(sol2.isHappy(input))
44 | }
45 |
46 | func testHappyNumber2() {
47 | let input = 7
48 | /**
49 | 7^2 = 49
50 | 4^2 + 9^2 = 97
51 | 9^2 + 7^2 = 130
52 | 1^2 + 3^2 + 0^2 = 10
53 | 1^2 + 0^2 = 1
54 | */
55 | XCTAssertTrue(sol2.isHappy(input))
56 | }
57 |
58 | func testHappyNumber3() {
59 | let input = 9
60 | /**
61 | 9^2 = 81
62 | 8^2 + 1^2 = 65
63 | 6^2 + 5^2 = 61
64 | 6^2 + 1^2 = 37
65 | 3^2 + 7^2 = 58
66 | 5^2 + 8^2 = 89
67 | 8*2 + 9^2 = 145
68 | 1^2 + 4^2 + 5^2 = 42
69 | 4^2 + 2^2 = 20
70 | 2^2 + 0^2 = 4
71 | 4^2 = 16 (duplicate, which has the same result as 61. Cycle detected)
72 | */
73 | XCTAssertFalse(sol2.isHappy(input))
74 | }
75 |
76 | // MARK: - Day 3: Maximum Subarray Tests
77 | func testMaxSubArray1() {
78 | let input = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
79 | // Explanation: [4,-1,2,1] has the largest sum = 6.
80 | let expected = 6
81 | XCTAssertEqual(sol3.maxSubArray(input), expected)
82 | }
83 |
84 | func testMaxSubArray2() {
85 | let input = [1, 2, 7, -8, -4, 3, 85, -32, 20]
86 | let expected = 88
87 | XCTAssertEqual(sol3.maxSubArray(input), expected)
88 | }
89 |
90 | // MARK: - Day 4: Maximum Subarray Tests
91 | func testMoveZeroes1() {
92 | var input = [0, 1, 0, 3, 12]
93 | let expected = [1, 3, 12, 0, 0]
94 | sol4.moveZeroes(&input)
95 | XCTAssertEqual(input, expected)
96 | }
97 |
98 | func testMoveZeroes2() {
99 | var input = [0, 0, 0, 0, 0, 1]
100 | let expected = [1, 0, 0, 0, 0, 0]
101 | sol4.moveZeroes(&input)
102 | XCTAssertEqual(input, expected)
103 | }
104 |
105 | // MARK: - Day 5: Best Time to Buy and Sell Stock II
106 | func testMakeProfit1() {
107 | let input = [7, 1, 5, 3, 6, 4]
108 | let expected = 7
109 | XCTAssertEqual(sol5.maxProfit(input), expected)
110 | }
111 |
112 | func testMakeProfit2() {
113 | let input = [1, 2, 3, 4, 5]
114 | let expected = 4
115 | XCTAssertEqual(sol5.maxProfit(input), expected)
116 | }
117 |
118 | // MARK: - Day 6: Group Anagrams
119 | func testGroupAnagrams1() {
120 | let input = ["eat", "tea", "tan", "ate", "nat", "bat"]
121 | let expected = [
122 | ["ate","eat","tea"],
123 | ["nat","tan"],
124 | ["bat"]
125 | ]
126 | XCTAssertTrue(expected.compareTo2DArrayIgnoreOrder(sol6.groupAnagrams(input)))
127 | }
128 |
129 | func testGroupAnagrams2() {
130 | let input = ["","",""]
131 | let expected = [
132 | ["","",""]
133 | ]
134 | XCTAssertTrue(expected.compareTo2DArrayIgnoreOrder(sol6.groupAnagrams(input)))
135 | }
136 |
137 | // MARK: - Day 7: Counting Elements
138 | func testCountingElements1() {
139 | let input = [1, 2, 3]
140 | let expected = 2
141 | XCTAssertEqual(expected, sol7.countElements(input))
142 | }
143 |
144 | func testCountingElements2() {
145 | let input = [1, 1, 3, 3, 5, 5, 7, 7]
146 | let expected = 0
147 | XCTAssertEqual(expected, sol7.countElements(input))
148 | }
149 |
150 | func testCountingElements3() {
151 | let input = [1, 3, 2, 3, 5, 0]
152 | let expected = 3
153 | XCTAssertEqual(expected, sol7.countElements(input))
154 | }
155 |
156 | func testCountingElements4() {
157 | let input = [1, 1, 2, 2]
158 | let expected = 2
159 | XCTAssertEqual(expected, sol7.countElements(input))
160 | }
161 |
162 | // TODO: Performance tests comes later
163 | func testPerformanceExample() throws {
164 | // This is an example of a performance test case.
165 | self.measure {
166 | // Put the code you want to measure the time of here.
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsAprilWeek2.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsWeek2.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 4/15/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | // April Edition
12 | class TestsAprilWeek2: XCTestCase {
13 | let sol8 = AprilSolDay8()
14 | let sol9 = AprilSolDay9()
15 | let sol11 = AprilSolDay11()
16 | let sol12 = AprilSolDay12()
17 | let sol13 = AprilSolDay13()
18 | let sol14 = AprilSolDay14()
19 |
20 | // MARK: - Day 8: Middle of the Linked List
21 | func testMiddleNode1() {
22 | let input = [1, 2, 3, 4, 5].convertToLinkedList()
23 | let expected = [3, 4, 5].convertToLinkedList()
24 | let output = sol8.middleNode(input)
25 |
26 | XCTAssertNotNil(output)
27 | XCTAssertTrue(output!.isEqualToLinkedList(expected))
28 | }
29 |
30 | func testMiddleNode2() {
31 | let input = [2, 4, 6, 8, 10, 12].convertToLinkedList()
32 | let expected = [8, 10, 12].convertToLinkedList()
33 | let output = sol8.middleNode(input)
34 |
35 | XCTAssertNotNil(output)
36 | XCTAssertTrue(output!.isEqualToLinkedList(expected))
37 | }
38 |
39 | // MARK: - Day 9: Backspace String Compare
40 | func testBackspaceStringCompare1() {
41 | let input = (S: "ab#c", T: "ad#c")
42 | XCTAssertTrue(sol9.backspaceCompare(input.S, input.T))
43 | }
44 |
45 | func testBackspaceStringCompare2() {
46 | let input = (S: "a##c", T: "#a#c")
47 | XCTAssertTrue(sol9.backspaceCompare(input.S, input.T))
48 | }
49 |
50 | func testBackspaceStringCompare3() {
51 | let input = (S: "ab##", T: "c#d#")
52 | XCTAssertTrue(sol9.backspaceCompare(input.S, input.T))
53 | }
54 |
55 | func testBackspaceStringCompare4() {
56 | let input = (S: "a#c", T: "b")
57 | XCTAssertFalse(sol9.backspaceCompare(input.S, input.T))
58 | }
59 |
60 | // MARK: - Day 10: Min Stack
61 | func testMinStack1() {
62 | let minStack = AprilSolDay10.MinStack()
63 | minStack.push(-2)
64 | minStack.push(0)
65 | minStack.push(-3)
66 | minStack.push(-6)
67 | minStack.push(3)
68 | minStack.push(7)
69 | XCTAssertEqual(-6, minStack.getMin())
70 |
71 | minStack.pop()
72 | XCTAssertEqual(3, minStack.top())
73 |
74 | minStack.pop()
75 | minStack.pop()
76 | XCTAssertEqual(-3, minStack.getMin())
77 | }
78 |
79 | func testMinStack2() {
80 | let minStack = AprilSolDay10.MinStack()
81 | minStack.push(-2)
82 | minStack.push(-13)
83 | minStack.push(8)
84 | XCTAssertEqual(8, minStack.top())
85 |
86 | minStack.push(-20)
87 | XCTAssertEqual(-20, minStack.getMin())
88 |
89 | minStack.pop()
90 | XCTAssertEqual(-13, minStack.getMin())
91 |
92 | minStack.pop()
93 | minStack.pop()
94 | XCTAssertEqual(-2, minStack.getMin())
95 | }
96 |
97 | // MARK: - Day 11: Diameter of Binary Tree
98 | func testDiameterOfBinaryTree1() {
99 | /**
100 | Tree structure
101 | 1
102 | / \
103 | 2 3
104 | / \
105 | 4 5
106 | */
107 | let tree = [
108 | 1,
109 | 2, 3,
110 | 4, 5, nil, nil
111 | ].convertToBinaryTree()
112 | let expected = 3
113 | XCTAssertEqual(expected, sol11.diameterOfBinaryTree(tree))
114 | }
115 |
116 | func testDiameterOfBinaryTree2() {
117 | /**
118 | Tree structure
119 | 4
120 | / \
121 | 7 3
122 | / \
123 | 9 3
124 | / \ /
125 | 9 7 4
126 | / / \
127 | 6 6 6
128 | / \ / /
129 | 0 6 5 9
130 | */
131 | let tree = [
132 | 4,
133 | 7, 3,
134 | nil, nil, 9, 3,
135 | nil, nil, nil, nil, 9, 7, 4, nil,
136 | nil, nil, nil, nil, nil, nil, nil, nil, 6, nil, 6, 6, nil, nil, nil, nil,
137 | nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 6, nil, nil, 5, nil, 9, nil, nil, nil, nil, nil, nil, nil, nil, nil
138 | ].convertToBinaryTree()
139 | let expected = 6
140 | XCTAssertEqual(expected, sol11.diameterOfBinaryTree(tree))
141 | }
142 |
143 | // MARK: - Day 12: Last Stone Weight
144 | func testLastStoneWeight1() {
145 | let input = [2, 7, 4, 1, 8, 1]
146 | let expected = 1
147 | XCTAssertEqual(expected, sol12.lastStoneWeight(input))
148 | }
149 |
150 | func testLastStoneWeight2() {
151 | let input = [10, 5, 7, 23, 11, 12, 27, 19]
152 | let expected = 0
153 | XCTAssertEqual(expected, sol12.lastStoneWeight(input))
154 | }
155 |
156 | // MARK: - Day 13: Contiguous Array
157 | func testContiguousArray1() {
158 | let input = [0, 1]
159 | let expected = 2
160 | XCTAssertEqual(expected, sol13.findMaxLength(input))
161 | }
162 |
163 | func testContiguousArray2() {
164 | let input = [0, 1, 0]
165 | let expected = 2
166 | XCTAssertEqual(expected, sol13.findMaxLength(input))
167 | }
168 |
169 | func testContiguousArray3() {
170 | let input = [0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
171 | let expected = 8
172 | XCTAssertEqual(expected, sol13.findMaxLength(input))
173 | }
174 |
175 | func testContiguousArray4() {
176 | let input = [0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0]
177 | let expected = 12
178 | XCTAssertEqual(expected, sol13.findMaxLength(input))
179 | }
180 |
181 | // MARK: - Day 14: Perform String Shifts
182 | func testPerformStringShifts1() {
183 | let input = (s: "abc", shift: [[0,1], [1,2]])
184 | let expected = "cab"
185 | XCTAssertEqual(expected, sol14.stringShift(input.s, input.shift))
186 | }
187 |
188 | func testPerformStringShifts2() {
189 | let input = (s: "abcdefg", shift: [[1, 1], [1, 1], [0, 2], [1, 3]])
190 | let expected = "efgabcd"
191 | XCTAssertEqual(expected, sol14.stringShift(input.s, input.shift))
192 | }
193 |
194 | func testPerformStringShifts3() {
195 | let input = (s: "michaelh", shift: [[1, 1], [1, 1], [1, 8], [0, 6], [1, 17]])
196 | let expected = "haelhmic"
197 | XCTAssertEqual(expected, sol14.stringShift(input.s, input.shift))
198 | }
199 |
200 | // TODO: Performance tests comes later
201 | func testPerformanceExample() throws {
202 | // This is an example of a performance test case.
203 | self.measure {
204 | // Put the code you want to measure the time of here.
205 | }
206 | }
207 | }
208 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsAprilWeek3.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsWeek3.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 4/20/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | // April Edition
12 | class TestsAprilWeek3: XCTestCase {
13 | let sol15 = AprilSolDay15()
14 | let sol16 = AprilSolDay16()
15 | let sol17 = AprilSolDay17()
16 | let sol18 = AprilSolDay18()
17 | let sol19 = AprilSolDay19()
18 | let sol20 = AprilSolDay20()
19 | let sol21 = AprilSolDay21()
20 |
21 | // MARK: - Day 15: Product of Array Except Self
22 | func testProductExceptSelf1() {
23 | let input = [1, 2, 3, 4]
24 | let expected = [24,12,8,6]
25 |
26 | XCTAssertEqual(expected, sol15.productExceptSelf(input))
27 | }
28 |
29 | func testMiddleNode2() {
30 | let input = [0, 0]
31 | let expected = [0, 0]
32 |
33 | XCTAssertEqual(expected, sol15.productExceptSelf(input))
34 | }
35 |
36 | // MARK: - Day 16: Valid Parenthesis String
37 | func testValidParenthesisString1() {
38 | let input = "()"
39 | XCTAssertTrue(sol16.checkValidString(input))
40 | }
41 |
42 | func testValidParenthesisString2() {
43 | let input = "(*))"
44 | XCTAssertTrue(sol16.checkValidString(input))
45 | }
46 |
47 | func testValidParenthesisString3() {
48 | let input = "(*()"
49 | XCTAssertTrue(sol16.checkValidString(input))
50 | }
51 |
52 | func testValidParenthesisString4() {
53 | let input = "("
54 | XCTAssertFalse(sol16.checkValidString(input))
55 | }
56 |
57 | func testValidParenthesisString5() {
58 | let input = "(*)"
59 | XCTAssertTrue(sol16.checkValidString(input))
60 | }
61 |
62 | func testValidParenthesisString6() {
63 | let input = "(())((())()()(*)(*()(())())())()()((()())((()))(*"
64 | XCTAssertFalse(sol16.checkValidString(input))
65 | }
66 |
67 | func testValidParenthesisString7() {
68 | let input = "(()(())()())*((()(())))*()(*)()()(*((()((*(*))))()*()(()((()(*((()))*(((())(())))*))(()*))(()*)"
69 | XCTAssertTrue(sol16.checkValidString(input))
70 | }
71 |
72 | // MARK: - Day 17: Number of Islands
73 | func testNumberOfIslands1() {
74 | let input: [[Character]] = [
75 | ["1", "1", "0", "0", "0"],
76 | ["1", "1", "0", "0", "0"],
77 | ["0", "0", "1", "0", "0"],
78 | ["0", "0", "0", "1", "1"]
79 | ]
80 | let expected = 3
81 | XCTAssertEqual(expected, sol17.numIslands(input))
82 | }
83 |
84 | func testNumberOfIslands2() {
85 | let input: [[Character]] = [
86 | ["1", "1", "1", "1", "0"],
87 | ["1", "1", "0", "1", "0"],
88 | ["1", "1", "0", "0", "0"],
89 | ["0", "0", "0", "0", "0"]
90 | ]
91 | let expected = 1
92 | XCTAssertEqual(expected, sol17.numIslands(input))
93 | }
94 |
95 | func testNumberOfIslands3() {
96 | let input: [[Character]] = [
97 | ["0", "0", "0", "0", "0"],
98 | ["0", "1", "1", "1", "0"],
99 | ["0", "0", "0", "0", "0"],
100 | ["0", "0", "0", "0", "0"]
101 | ]
102 | let expected = 1
103 | XCTAssertEqual(expected, sol17.numIslands(input))
104 | }
105 |
106 | // MARK: - Day 18: Minimum Path Sum
107 | func testMinimumPathSum1() {
108 | let input = [
109 | [1, 3, 1],
110 | [1, 5, 1],
111 | [4, 2, 1]
112 | ]
113 | let expected = 7
114 | XCTAssertEqual(expected, sol18.minPathSum(input))
115 | }
116 |
117 | func testMinimumPathSum2() {
118 | let input = [
119 | [1, 2, 5],
120 | [3, 2, 1]
121 | ]
122 | let expected = 6
123 | XCTAssertEqual(expected, sol18.minPathSum(input))
124 | }
125 |
126 | // MARK: - Day 19: Search in Rotated Sorted Array
127 | func testSearchRotatedSortedArray1() {
128 | let input = (nums: [4, 5, 6, 7, 0, 1, 2], target: 0)
129 | let expected = 4
130 | XCTAssertEqual(expected, sol19.search(input.nums, input.target))
131 | }
132 |
133 | func testSearchRotatedSortedArray2() {
134 | let input = (nums: [4, 5, 6, 7, 0, 1, 2], target: 3)
135 | let expected = -1
136 | XCTAssertEqual(expected, sol19.search(input.nums, input.target))
137 | }
138 |
139 | func testSearchRotatedSortedArray3() {
140 | let input = (nums: [Int](), target: 5)
141 | let expected = -1
142 | XCTAssertEqual(expected, sol19.search(input.nums, input.target))
143 | }
144 |
145 | func testSearchRotatedSortedArray4() {
146 | let input = (nums: [3, 1], target: 1)
147 | let expected = 1
148 | XCTAssertEqual(expected, sol19.search(input.nums, input.target))
149 | }
150 |
151 | // MARK: - Day 20: Construct Binary Search Tree from Preorder Traversal
152 | func testConstructBSTFromPreorderTraversal1() {
153 | let input = [8, 5, 1, 7, 10, 12]
154 | /**
155 | Tree structure
156 | 8
157 | / \
158 | 5 10
159 | / \ \
160 | 1 7 12
161 | */
162 | let expected = [
163 | 8,
164 | 5, 10,
165 | 1, 7, nil, 12
166 | ].convertToBinaryTree()
167 |
168 | let output = BinarySearchTree(root: sol20.bstFromPreorder(input))
169 | XCTAssertTrue(output.isEqualToOtherTree(expected))
170 | }
171 |
172 | func testConstructBSTFromPreorderTraversal2() {
173 | let input = [9, 5, 3, 8, 10, 15, 13, 19, 25]
174 | /**
175 | Tree structure
176 | 9
177 | / \
178 | 5 10
179 | / \ \
180 | 3 8 15
181 | / \
182 | 13 19
183 | \
184 | 25
185 | */
186 | let expected = [
187 | 9,
188 | 5, 10,
189 | 3, 8, nil, 15,
190 | nil, nil, nil, nil, nil, nil, 13, 19,
191 | nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 25
192 | ].convertToBinaryTree()
193 |
194 | let output = BinarySearchTree(root: sol20.bstFromPreorder(input))
195 | XCTAssertTrue(output.isEqualToOtherTree(expected))
196 | }
197 |
198 | // MARK: - Day 21: Leftmost Column with at Least a One
199 | func testLeftmostColumnWithAtLeastOne1() {
200 | let input = [
201 | [0, 0, 0, 1],
202 | [0, 0, 1, 1],
203 | [0, 1, 1, 1]
204 | ]
205 | let expected = 1
206 | let bm = TestBinaryMatrix(matrix: input)
207 | XCTAssertEqual(expected, sol21.leftMostColumnWithOne(bm))
208 | }
209 |
210 | func testLeftmostColumnWithAtLeastOne2() {
211 | let input = [
212 | [0, 0],
213 | [0, 0]
214 | ]
215 | let expected = -1
216 | let bm = TestBinaryMatrix(matrix: input)
217 | XCTAssertEqual(expected, sol21.leftMostColumnWithOne(bm))
218 | }
219 |
220 | func testLeftmostColumnWithAtLeastOne3() {
221 | let input = [
222 | [0, 0, 0, 0, 1],
223 | [0, 0, 1, 1, 1],
224 | [0, 0, 0, 1, 1],
225 | [0, 1, 1, 1, 1],
226 | [0, 0, 0, 0, 0],
227 | [1, 1, 1, 1, 1],
228 | ]
229 | let expected = 0
230 | let bm = TestBinaryMatrix(matrix: input)
231 | XCTAssertEqual(expected, sol21.leftMostColumnWithOne(bm))
232 | }
233 |
234 |
235 | // TODO: Performance tests comes later
236 | func testPerformanceExample() throws {
237 | // This is an example of a performance test case.
238 | self.measure {
239 | // Put the code you want to measure the time of here.
240 | }
241 | }
242 | }
243 |
244 | /**
245 | [
246 | [0,0,1,1,1,1,1,1],
247 | [0,0,0,0,0,1,1,1],
248 | [0,0,0,1,1,1,1,1],
249 | [0,0,0,0,0,1,1,1],
250 | [0,0,0,1,1,1,1,1],
251 | [0,0,1,1,1,1,1,1],
252 | [0,0,0,0,1,1,1,1],
253 | [0,1,1,1,1,1,1,1]
254 | ]
255 | */
256 |
257 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsAprilWeek4.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsWeek4.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 4/27/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | // April Edition
12 | class TestsAprilWeek4: XCTestCase {
13 | let sol22 = AprilSolDay22()
14 | let sol23 = AprilSolDay23()
15 | let sol25 = AprilSolDay25()
16 | let sol26 = AprilSolDay26()
17 | let sol27 = AprilSolDay27()
18 |
19 | // MARK: - Day 22: Subarray Sum Equals K
20 | func testSubarraySumEqualsK1() {
21 | let input = (nums: [1, 1, 1, 3, 8, 9], k: 5)
22 | let expected = 1
23 |
24 | XCTAssertEqual(expected, sol22.subarraySum(input.nums, input.k))
25 | }
26 |
27 | func testSubarraySumEqualsK2() {
28 | let input = (nums: [1, 1, 1], k: 2)
29 | let expected = 2
30 |
31 | XCTAssertEqual(expected, sol22.subarraySum(input.nums, input.k))
32 | }
33 |
34 | // MARK: - Day 23: Bitwise AND of Numbers Range
35 | func testBitwiseANDOfNumbersRange1() {
36 | let input = (5, 7)
37 | let expected = 4
38 | XCTAssertEqual(expected, sol23.rangeBitwiseAnd(input.0, input.1))
39 | }
40 |
41 | func testBitwiseANDOfNumbersRange2() {
42 | let input = (0, 1)
43 | let expected = 0
44 | XCTAssertEqual(expected, sol23.rangeBitwiseAnd(input.0, input.1))
45 | }
46 |
47 | // MARK: - Day 24: LRU Cache
48 | func testLRUCache1() {
49 | let cache = AprilSolDay24.LRUCache(2)
50 | cache.put(1, 1)
51 | cache.put(2, 2)
52 | XCTAssertEqual(1, cache.get(1))
53 |
54 | cache.put(3, 3)
55 | XCTAssertEqual(-1, cache.get(2))
56 |
57 | cache.put(4, 4)
58 | XCTAssertEqual(-1, cache.get(1))
59 | XCTAssertEqual(3, cache.get(3))
60 | XCTAssertEqual(4, cache.get(4))
61 | }
62 |
63 | func testLRUCache2() {
64 | let cache = AprilSolDay24.LRUCache(5)
65 | cache.put(1, 10)
66 | cache.put(2, 20)
67 | cache.put(3, 30)
68 | cache.put(4, 40)
69 | cache.put(5, 50)
70 | cache.put(4, 41)
71 | XCTAssertEqual(10, cache.get(1))
72 |
73 | cache.put(6, 60)
74 | XCTAssertEqual(-1, cache.get(2))
75 |
76 | cache.put(7, 70)
77 | XCTAssertEqual(-1, cache.get(3))
78 | XCTAssertEqual(41, cache.get(4))
79 | XCTAssertEqual(60, cache.get(6))
80 | }
81 |
82 | // MARK: - Day 25: Jump Game
83 | func testJumpGame1() {
84 | let input = [2, 3, 1, 1, 4]
85 | XCTAssertTrue(sol25.canJump(input))
86 | }
87 |
88 | func testJumpGame2() {
89 | let input = [3, 2, 1, 0, 4]
90 | XCTAssertFalse(sol25.canJump(input))
91 | }
92 |
93 | func testJumpGame3() {
94 | let input = [1, 2, 3]
95 | XCTAssertTrue(sol25.canJump(input))
96 | }
97 |
98 | // MARK: - Day 26: Longest Common Subsequence
99 | func testLongestCommonSubsequence1() {
100 | let input = ("abcde", "ace")
101 | let expected = 3
102 | XCTAssertEqual(expected, sol26.longestCommonSubsequence(input.0, input.1))
103 | }
104 |
105 | func testLongestCommonSubsequence2() {
106 | let input = ("abc", "def")
107 | let expected = 0
108 | XCTAssertEqual(expected, sol26.longestCommonSubsequence(input.0, input.1))
109 | }
110 |
111 | func testLongestCommonSubsequence3() {
112 | let input = ("abc", "abc")
113 | let expected = 3
114 | XCTAssertEqual(expected, sol26.longestCommonSubsequence(input.0, input.1))
115 | }
116 |
117 | func testLongestCommonSubsequence4() {
118 | let input = ("pmjghexybyrgzczy", "hafcdqbgncrcbihkd")
119 | let expected = 4
120 | XCTAssertEqual(expected, sol26.longestCommonSubsequence(input.0, input.1))
121 | }
122 |
123 | func testLongestCommonSubsequence5() {
124 | let input = ("hofubmnylkra", "pqhgxgdofcvmr")
125 | let expected = 5
126 | XCTAssertEqual(expected, sol26.longestCommonSubsequence(input.0, input.1))
127 | }
128 |
129 | // MARK: - Day 27: Maximal Square
130 | func testMaximalSquare1() {
131 | let input: [[Character]] = [
132 | ["1", "0", "1", "0", "0"],
133 | ["1", "0", "1", "1", "1"],
134 | ["1", "1", "1", "1", "1"],
135 | ["1", "0", "0", "1", "0"]
136 | ]
137 | let expected = 4
138 | XCTAssertEqual(expected, sol27.maximalSquare(input))
139 | }
140 |
141 | func testMaximalSquare2() {
142 | let input: [[Character]] = [
143 | ["1", "0", "0", "1", "0"],
144 | ["1", "1", "1", "1", "1"],
145 | ["1", "1", "1", "1", "1"],
146 | ["1", "1", "1", "1", "0"]
147 | ]
148 | let expected = 9
149 | XCTAssertEqual(expected, sol27.maximalSquare(input))
150 | }
151 |
152 | // MARK: - Day 28: First Unique Number
153 | func testFirstUniqueNumber1() {
154 | let firstUnique = AprilSolDay28.FirstUnique([2, 3, 5])
155 | XCTAssertEqual(2, firstUnique.showFirstUnique())
156 | firstUnique.add(5)
157 | XCTAssertEqual(2, firstUnique.showFirstUnique())
158 | firstUnique.add(2)
159 | XCTAssertEqual(3, firstUnique.showFirstUnique())
160 | firstUnique.add(3)
161 | XCTAssertEqual(-1, firstUnique.showFirstUnique())
162 | }
163 |
164 | func testFirstUniqueNumber2() {
165 | let firstUnique = AprilSolDay28.FirstUnique([7, 7, 7, 7, 7, 7])
166 | XCTAssertEqual(-1, firstUnique.showFirstUnique())
167 | firstUnique.add(7)
168 | firstUnique.add(3)
169 | firstUnique.add(3)
170 | firstUnique.add(17)
171 | XCTAssertEqual(17, firstUnique.showFirstUnique())
172 | }
173 |
174 | func testFirstUniqueNumber3() {
175 | let firstUnique = AprilSolDay28.FirstUnique([809])
176 | XCTAssertEqual(809, firstUnique.showFirstUnique())
177 | firstUnique.add(809)
178 | XCTAssertEqual(-1, firstUnique.showFirstUnique())
179 | }
180 |
181 | func testPerformanceExample() throws {
182 | // This is an example of a performance test case.
183 | self.measure {
184 | // Put the code you want to measure the time of here.
185 | }
186 | }
187 |
188 | }
189 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsAprilWeek5.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsWeek5.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 5/1/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | // April Edition
12 | class TestsAprilWeek5: XCTestCase {
13 | let sol29 = AprilSolDay29()
14 | let sol30 = AprilSolDay30()
15 |
16 | // MARK: - Day 29: Binary Tree Maximum Path Sum
17 | func testBinaryTreeMaximumPathSum1() {
18 | /**
19 | Tree structure
20 | 1
21 | / \
22 | 2 3
23 | */
24 | let tree = [
25 | 1,
26 | 2, 3
27 | ].convertToBinaryTree()
28 | let expected = 6
29 | XCTAssertEqual(expected, sol29.maxPathSum(tree))
30 | }
31 |
32 | func testBinaryTreeMaximumPathSum2() {
33 | /**
34 | Tree structure
35 | -10
36 | / \
37 | 9 20
38 | / \
39 | 15 7
40 | */
41 | let tree = [
42 | -10,
43 | 9, 20,
44 | nil, nil, 15, 7
45 | ].convertToBinaryTree()
46 | let expected = 42
47 | XCTAssertEqual(expected, sol29.maxPathSum(tree))
48 | }
49 |
50 | func testBinaryTreeMaximumPathSum3() {
51 | /**
52 | Tree structure
53 | 5
54 | / \
55 | 4 8
56 | / / \
57 | 11 13 4
58 | / \ \
59 | 7 2 1
60 | */
61 | let tree = [
62 | 5,
63 | 4, 8,
64 | 11, nil, 13, 4,
65 | 7, 2, nil, nil, nil, nil, nil, 1
66 | ].convertToBinaryTree()
67 | let expected = 48
68 | XCTAssertEqual(expected, sol29.maxPathSum(tree))
69 | }
70 |
71 | // MARK: - Day 30: Check If a String Is a Valid Sequence from Root to Leaves Path in a Binary Tree
72 | func testIsValidSequenceInTree1() {
73 | /**
74 | Tree structure
75 | 0
76 | / \
77 | 1 0
78 | / \ /
79 | 0 1 0
80 | \ / \
81 | 1 0 0
82 | */
83 | let tree = [
84 | 0,
85 | 1, 0,
86 | 0, 1, 0, nil,
87 | nil, 1, 0, 0, nil, nil, nil, nil
88 | ].convertToBinaryTree()
89 | let arr = [0, 1, 0, 1]
90 | XCTAssertTrue(sol30.isValidSequence(tree, arr))
91 | }
92 |
93 | func testIsValidSequenceInTree2() {
94 | /**
95 | Tree structure
96 | 0
97 | / \
98 | 1 0
99 | / \ /
100 | 0 1 0
101 | \ / \
102 | 1 0 0
103 | */
104 | let tree = [
105 | 0,
106 | 1, 0,
107 | 0, 1, 0, nil,
108 | nil, 1, 0, 0, nil, nil, nil, nil
109 | ].convertToBinaryTree()
110 | let arr = [0, 0, 1]
111 | XCTAssertFalse(sol30.isValidSequence(tree, arr))
112 | }
113 |
114 | func testIsValidSequenceInTree3() {
115 | /**
116 | Tree structure
117 | 0
118 | / \
119 | 1 0
120 | / \ /
121 | 0 1 0
122 | \ / \
123 | 1 0 0
124 | */
125 | let tree = [
126 | 0,
127 | 1, 0,
128 | 0, 1, 0, nil,
129 | nil, 1, 0, 0, nil, nil, nil, nil
130 | ].convertToBinaryTree()
131 | let arr = [0, 1, 1]
132 | XCTAssertFalse(sol30.isValidSequence(tree, arr))
133 | }
134 |
135 | func testPerformanceExample() throws {
136 | // This is an example of a performance test case.
137 | self.measure {
138 | // Put the code you want to measure the time of here.
139 | }
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsMayWeek1.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsMayWeek1.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 5/3/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | // May Edition
12 | class TestsMayWeek1: XCTestCase {
13 | let sol1 = MaySolDay1()
14 | let sol2 = MaySolDay2()
15 | let sol3 = MaySolDay3()
16 | let sol4 = MaySolDay4()
17 | let sol5 = MaySolDay5()
18 | let sol6 = MaySolDay6()
19 | let sol7 = MaySolDay7()
20 |
21 | // MARK: - Day 1: First Bad Version
22 | func testFirstBadVersion1() {
23 | let expected = 4
24 | sol1.setBadVersion(expected)
25 | let input = 5
26 | XCTAssertEqual(expected, sol1.firstBadVersion(input))
27 | }
28 |
29 | func testFirstBadVersion2() {
30 | let expected = 37
31 | sol1.setBadVersion(expected)
32 | let input = 50
33 | XCTAssertEqual(expected, sol1.firstBadVersion(input))
34 | }
35 |
36 | // MARK: - Day 2: Jewels and Stones
37 | func testJewelsAndStones1() {
38 | let input = (J: "aA", S: "aAAbbbb")
39 | let expected = 3
40 | XCTAssertEqual(expected, sol2.numJewelsInStones(input.J, input.S))
41 | }
42 |
43 | func testJewelsAndStones2() {
44 | let input = (J: "z", S: "ZZ")
45 | let expected = 0
46 | XCTAssertEqual(expected, sol2.numJewelsInStones(input.J, input.S))
47 | }
48 |
49 | // MARK: - Day 3: Ransom Note
50 | func testRansomNote1() {
51 | let input = (ransomNote: "a", magazine: "b")
52 | XCTAssertFalse(sol3.canConstruct(input.ransomNote, input.magazine))
53 | }
54 |
55 | func testRansomNote2() {
56 | let input = (ransomNote: "aa", magazine: "ab")
57 | XCTAssertFalse(sol3.canConstruct(input.ransomNote, input.magazine))
58 | }
59 |
60 | func testRansomNote3() {
61 | let input = (ransomNote: "aa", magazine: "aab")
62 | XCTAssertTrue(sol3.canConstruct(input.ransomNote, input.magazine))
63 | }
64 |
65 | // MARK: - Day 4: Number Complement
66 | func testNumberComplement1() {
67 | let input = 5
68 | let expected = 2
69 | XCTAssertEqual(expected, sol4.findComplement(input))
70 | }
71 |
72 | func testNumberComplement2() {
73 | let input = 1
74 | let expected = 0
75 | XCTAssertEqual(expected, sol4.findComplement(input))
76 | }
77 |
78 | // MARK: - Day 5: First Unique Character in a String
79 | func testFirstUniqueCharacterInString1() {
80 | let input = "leetcode"
81 | let expected = 0
82 | XCTAssertEqual(expected, sol5.firstUniqChar(input))
83 | }
84 |
85 | func testFirstUniqueCharacterInString2() {
86 | let input = "loveleetcode"
87 | let expected = 2
88 | XCTAssertEqual(expected, sol5.firstUniqChar(input))
89 | }
90 |
91 | // MARK: - Day 6: Majority Element
92 | func testMajorityElement1() {
93 | let input = [3, 2, 3]
94 | let expected = 3
95 | XCTAssertEqual(expected, sol6.majorityElement(input))
96 | }
97 |
98 | func testMajorityElement2() {
99 | let input = [2, 2, 1, 1, 1, 2, 2]
100 | let expected = 2
101 | XCTAssertEqual(expected, sol6.majorityElement(input))
102 | }
103 |
104 | // MARK: - Day 7: Cousins in Binary Tree
105 | func testCousinsInBinaryTree1() {
106 | /**
107 | Tree structure
108 | 1
109 | / \
110 | 2 3
111 | /
112 | 4
113 | */
114 | let tree = [
115 | 1,
116 | 2, 3,
117 | 4, nil, nil, nil
118 | ].convertToBinaryTree()
119 | let input = (x: 4, y: 3)
120 | XCTAssertFalse(sol7.isCousins(tree, input.x, input.y))
121 | }
122 |
123 | func testCousinsInBinaryTree2() {
124 | /**
125 | Tree structure
126 | 1
127 | / \
128 | 2 3
129 | \ \
130 | 4 5
131 | */
132 | let tree = [
133 | 1,
134 | 2, 3,
135 | nil, 4, nil, 5
136 | ].convertToBinaryTree()
137 | let input = (x: 5, y: 4)
138 | XCTAssertTrue(sol7.isCousins(tree, input.x, input.y))
139 | }
140 |
141 | func testCousinsInBinaryTree3() {
142 | /**
143 | Tree structure
144 | 1
145 | / \
146 | 2 3
147 | \
148 | 4
149 | */
150 | let tree = [
151 | 1,
152 | 2, 3,
153 | nil, 4, nil, nil
154 | ].convertToBinaryTree()
155 | let input = (x: 2, y: 3)
156 | XCTAssertFalse(sol7.isCousins(tree, input.x, input.y))
157 | }
158 |
159 | func testPerformanceExample() throws {
160 | // This is an example of a performance test case.
161 | self.measure {
162 | // Put the code you want to measure the time of here.
163 | }
164 | }
165 |
166 | }
167 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsMayWeek2.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsMayWeek2.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 5/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class TestsMayWeek2: XCTestCase {
12 | let sol8 = MaySolDay8()
13 | let sol9 = MaySolDay9()
14 | let sol10 = MaySolDay10()
15 | let sol11 = MaySolDay11()
16 | let sol12 = MaySolDay12()
17 | let sol13 = MaySolDay13()
18 |
19 | // MARK: - Day 8: Check If It Is a Straight Line
20 | func testCheckStraightLine1() {
21 | let input = [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]]
22 | XCTAssertTrue(sol8.checkStraightLine(input))
23 | }
24 |
25 | func testCheckStraightLine2() {
26 | let input = [[1, 1], [2, 2], [3, 4], [4, 5], [5, 6], [7, 7]]
27 | XCTAssertFalse(sol8.checkStraightLine(input))
28 | }
29 |
30 | func testCheckStraightLine3() {
31 | let input = [[-3, -2], [-1, -2], [2, -2], [-2, -2], [0, -2]]
32 | XCTAssertTrue(sol8.checkStraightLine(input))
33 | }
34 |
35 | // MARK: - Day 9: Valid Perfect Square
36 | func testIsPerfectSquare1() {
37 | let input = 16
38 | XCTAssertTrue(sol9.isPerfectSquare(input))
39 | }
40 |
41 | func testIsPerfectSquare2() {
42 | let input = 7
43 | XCTAssertFalse(sol9.isPerfectSquare(input))
44 | }
45 |
46 | func testIsPerfectSquare3() {
47 | let input = 100
48 | XCTAssertTrue(sol9.isPerfectSquare(input))
49 | }
50 |
51 | // MARK: - Day 10: Find the Town Judge
52 | func testFindJudge1() {
53 | let input = (N: 2, trust: [[1, 2]])
54 | XCTAssertEqual(2, sol10.findJudge(input.N, input.trust))
55 | }
56 |
57 | func testFindJudge2() {
58 | let input = (N: 3, trust: [[1, 3], [2, 3]])
59 | XCTAssertEqual(3, sol10.findJudge(input.N, input.trust))
60 | }
61 |
62 | func testFindJudge3() {
63 | let input = (N: 3, trust: [[1, 3], [2, 3], [3, 1]])
64 | XCTAssertEqual(-1, sol10.findJudge(input.N, input.trust))
65 | }
66 |
67 | func testFindJudge4() {
68 | let input = (N: 3, trust: [[1, 2], [2, 3]])
69 | XCTAssertEqual(-1, sol10.findJudge(input.N, input.trust))
70 | }
71 |
72 | func testFindJudge5() {
73 | let input = (N: 4, trust: [[1, 3], [1, 4], [2, 3], [2, 4], [4, 3]])
74 | XCTAssertEqual(3, sol10.findJudge(input.N, input.trust))
75 | }
76 |
77 | // MARK: - Day 11: Flood Fill
78 | func testFloodFill1() {
79 | let input = (image: [[1, 1, 1], [1, 1, 0], [1, 0, 1]], sr: 1, sc: 1, newColor: 2)
80 | let expected = [[2, 2, 2], [2, 2, 0], [2, 0,1 ]]
81 | XCTAssertEqual(expected, sol11.floodFill(input.image, input.sr, input.sc, input.newColor))
82 | }
83 |
84 | func testFloodFill2() {
85 | let input = (image: [[0,0,0],[0,0,0]], sr: 0, sc: 0, newColor: 2)
86 | let expected = [[2, 2, 2], [2, 2, 2]]
87 | XCTAssertEqual(expected, sol11.floodFill(input.image, input.sr, input.sc, input.newColor))
88 | }
89 |
90 | // MARK: - Day 12: Single Element in a Sorted Array
91 | func testSingleNonDuplicate1() {
92 | let input = [1, 1, 2, 3, 3, 4, 4, 8, 8]
93 | let expected = 2
94 | XCTAssertEqual(expected, sol12.singleNonDuplicate(input))
95 | }
96 |
97 | func testSingleNonDuplicate2() {
98 | let input = [3, 3, 7, 7, 10, 11, 11]
99 | let expected = 10
100 | XCTAssertEqual(expected, sol12.singleNonDuplicate(input))
101 | }
102 |
103 | // MARK: - Day 13: Remove K Digits
104 | func testRemoveKDigits1() {
105 | let input = (num: "1432219", k: 3)
106 | let expected = "1219"
107 | XCTAssertEqual(expected, sol13.removeKdigits(input.num, input.k))
108 | }
109 |
110 | func testRemoveKDigits2() {
111 | let input = (num: "10200", k: 1)
112 | let expected = "200"
113 | XCTAssertEqual(expected, sol13.removeKdigits(input.num, input.k))
114 | }
115 |
116 | func testRemoveKDigits3() {
117 | let input = (num: "10", k: 2)
118 | let expected = "0"
119 | XCTAssertEqual(expected, sol13.removeKdigits(input.num, input.k))
120 | }
121 |
122 | func testRemoveKDigits4() {
123 | let input = (num: "1234567890", k: 9)
124 | let expected = "0"
125 | XCTAssertEqual(expected, sol13.removeKdigits(input.num, input.k))
126 | }
127 |
128 | // MARK: - Day 14: Implement Trie (Prefix Tree)
129 | func testTrie1() {
130 | let trie = MaySolDay14.Trie()
131 |
132 | trie.insert("apple")
133 |
134 | XCTAssertTrue(trie.search("apple"))
135 | XCTAssertFalse(trie.search("app"))
136 |
137 | XCTAssertTrue(trie.startsWith("apple"))
138 | XCTAssertTrue(trie.startsWith("app"))
139 | XCTAssertFalse(trie.startsWith("pp"))
140 | }
141 |
142 | func testTrie2() {
143 | let trie = MaySolDay14.Trie()
144 |
145 | trie.insert("app")
146 | trie.insert("apple")
147 | trie.insert("beer")
148 | trie.insert("add")
149 | trie.insert("jam")
150 | trie.insert("rental")
151 |
152 | XCTAssertFalse(trie.search("apps"))
153 | XCTAssertTrue(trie.search("app"))
154 | XCTAssertFalse(trie.search("apps"))
155 | XCTAssertFalse(trie.search("ad"))
156 | XCTAssertFalse(trie.search("applepie"))
157 | XCTAssertFalse(trie.search("jan"))
158 | XCTAssertFalse(trie.search("rent"))
159 | XCTAssertTrue(trie.search("beer"))
160 | XCTAssertTrue(trie.search("jam"))
161 |
162 | XCTAssertFalse(trie.startsWith("apps"))
163 | XCTAssertTrue(trie.startsWith("app"))
164 | XCTAssertTrue(trie.startsWith("ad"))
165 | XCTAssertFalse(trie.startsWith("applepie"))
166 | XCTAssertFalse(trie.startsWith("rest"))
167 | XCTAssertFalse(trie.startsWith("jan"))
168 | XCTAssertTrue(trie.startsWith("rent"))
169 | XCTAssertTrue(trie.startsWith("beer"))
170 | XCTAssertTrue(trie.startsWith("jam"))
171 | }
172 |
173 | func testPerformanceExample() throws {
174 | // This is an example of a performance test case.
175 | self.measure {
176 | // Put the code you want to measure the time of here.
177 | }
178 | }
179 |
180 | }
181 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsMayWeek3.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsMayWeek3.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class TestsMayWeek3: XCTestCase {
12 | let sol15 = MaySolDay15()
13 | let sol16 = MaySolDay16()
14 | let sol17 = MaySolDay17()
15 | let sol20 = MaySolDay20()
16 | let sol21 = MaySolDay21()
17 |
18 | // MARK: - Day 15: Maximum Sum Circular Subarray
19 | func testMaxSubarraySumCircular1() {
20 | let input = [1,-2,3,-2]
21 | let expected = 3
22 | XCTAssertEqual(expected, sol15.maxSubarraySumCircular(input))
23 | }
24 |
25 | func testMaxSubarraySumCircular2() {
26 | let input = [5, -3, 5]
27 | let expected = 10
28 | XCTAssertEqual(expected, sol15.maxSubarraySumCircular(input))
29 | }
30 |
31 | func testMaxSubarraySumCircular3() {
32 | let input = [3, -1, 2, -1]
33 | let expected = 4
34 | XCTAssertEqual(expected, sol15.maxSubarraySumCircular(input))
35 | }
36 |
37 | func testMaxSubarraySumCircular4() {
38 | let input = [9, -4, -7, 9]
39 | let expected = 18
40 | XCTAssertEqual(expected, sol15.maxSubarraySumCircular(input))
41 | }
42 |
43 | func testMaxSubarraySumCircular5() {
44 | let input = [2, -2, 2, 7, 8, 0]
45 | let expected = 19
46 | XCTAssertEqual(expected, sol15.maxSubarraySumCircular(input))
47 | }
48 |
49 | // MARK: - Day 16: Odd Even Linked List
50 | func testOddEvenLinkedList1() {
51 | let input = [1, 2, 3, 4, 5].convertToLinkedList()
52 | let expected = [1, 3, 5, 2, 4].convertToLinkedList()
53 | XCTAssertTrue(sol16.oddEvenList(input)!.isEqualToLinkedList(expected))
54 | }
55 |
56 | func testOddEvenLinkedList2() {
57 | let input = [2, 1, 3, 5, 6, 4, 7].convertToLinkedList()
58 | let expected = [2, 3, 6, 7, 1, 5, 4].convertToLinkedList()
59 | XCTAssertTrue(sol16.oddEvenList(input)!.isEqualToLinkedList(expected))
60 | }
61 |
62 | // MARK: - Day 17: Find All Anagrams in a String
63 | func testFindAllAnagramsInString1() {
64 | let input = (s: "cbaebabacd", p: "abc")
65 | let expected = [0, 6]
66 | XCTAssertEqual(expected, sol17.findAnagrams(input.s, input.p))
67 | }
68 |
69 | func testFindAllAnagramsInString2() {
70 | let input = (s: "abab", p: "ab")
71 | let expected = [0, 1, 2]
72 | XCTAssertEqual(expected, sol17.findAnagrams(input.s, input.p))
73 | }
74 |
75 | // MARK: - Day 18: Permutation in String
76 |
77 | // MARK: - Day 19: Online Stock Span
78 | func testOnlineStockSpan1() {
79 | let stockSpanner = MaySolDay19.StockSpanner()
80 | XCTAssertEqual(1, stockSpanner.next(100))
81 | XCTAssertEqual(1, stockSpanner.next(80))
82 | XCTAssertEqual(1, stockSpanner.next(60))
83 | XCTAssertEqual(2, stockSpanner.next(70))
84 | XCTAssertEqual(1, stockSpanner.next(60))
85 | XCTAssertEqual(4, stockSpanner.next(75))
86 | XCTAssertEqual(6, stockSpanner.next(85))
87 | }
88 |
89 | // MARK: - Day 20: Kth Smallest Element in a BST
90 | func testKthSmallest1() {
91 | let input = (
92 | tree: [
93 | 3,
94 | 1, 4,
95 | nil, 2, nil, nil
96 | ].convertToBinaryTree(),
97 | k: 1
98 | )
99 | let expected = 1
100 | XCTAssertEqual(expected, sol20.kthSmallest(input.tree, input.k))
101 | }
102 |
103 | func testKthSmallest2() {
104 | let input = (
105 | tree: [
106 | 5,
107 | 3, 6,
108 | 2, 4, nil, nil,
109 | 1, nil, nil, nil, nil, nil, nil, nil
110 | ].convertToBinaryTree(),
111 | k: 3
112 | )
113 | let expected = 3
114 | XCTAssertEqual(expected, sol20.kthSmallest(input.tree, input.k))
115 | }
116 |
117 | // MARK: - Day 21: Count Square Submatrices with All Ones
118 | func testCountSquares1() {
119 | let input = [
120 | [0, 1, 1, 1],
121 | [1, 1, 1, 1],
122 | [0, 1, 1, 1]
123 | ]
124 | let expected = 15
125 | XCTAssertEqual(expected, sol21.countSquares(input))
126 | }
127 |
128 | func testCountSquares2() {
129 | let input = [
130 | [1, 0, 1],
131 | [1, 1, 0],
132 | [1, 1, 0]
133 | ]
134 | let expected = 7
135 | XCTAssertEqual(expected, sol21.countSquares(input))
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsMayWeek4.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsMayWeek4.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 5/31/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class TestsMayWeek4: XCTestCase {
12 | let sol22 = MaySolDay22()
13 | let sol23 = MaySolDay23()
14 | let sol24 = MaySolDay24()
15 | let sol25 = MaySolDay25()
16 | let sol26 = MaySolDay26()
17 | let sol27 = MaySolDay27()
18 | let sol28 = MaySolDay28()
19 |
20 | // MARK: - Day 22: Sort Characters By Frequency
21 | func testFrequencySort1() {
22 | let input = "tree"
23 | let expected1 = "eetr"
24 | let expected2 = "eert"
25 | let output = sol22.frequencySort(input)
26 | XCTAssertTrue(output == expected1 || output == expected2)
27 | }
28 |
29 | func testFrequencySort2() {
30 | let input = "cccaaa"
31 | let expected1 = "aaaccc"
32 | let expected2 = "cccaaa"
33 | let output = sol22.frequencySort(input)
34 | XCTAssertTrue(output == expected1 || output == expected2)
35 | }
36 |
37 | func testFrequencySort3() {
38 | let input = "Aabb"
39 | let expected1 = "bbAa"
40 | let expected2 = "bbaA"
41 | let output = sol22.frequencySort(input)
42 | XCTAssertTrue(output == expected1 || output == expected2)
43 | }
44 |
45 | // MARK: - Day 23: Interval List Intersections
46 | func testIntervalIntersection1() {
47 | let input = (A: [[0, 2],[5, 10], [13, 23], [24, 25]], B: [[1, 5], [8, 12], [15, 24], [25, 26]])
48 | let expected = [[1, 2], [5, 5], [8, 10], [15, 23], [24, 24], [25, 25]]
49 | XCTAssertEqual(expected, sol23.intervalIntersection(input.A, input.B))
50 | }
51 |
52 | func testIntervalIntersection2() {
53 | let input = (A: [[4, 6], [7, 8], [10, 17]], B: [[5, 10]])
54 | let expected = [[5, 6], [7, 8], [10, 10]]
55 | XCTAssertEqual(expected, sol23.intervalIntersection(input.A, input.B))
56 | }
57 |
58 | func testIntervalIntersection3() {
59 | let input = (A: [[1, 3], [5, 9]], B: [[Int]]())
60 | let expected = [[Int]]()
61 | XCTAssertEqual(expected, sol23.intervalIntersection(input.A, input.B))
62 | }
63 |
64 | // MARK: - Day 24: Construct Binary Search Tree from Preorder Traversal
65 | func testConstructBSTFromPreorderTraversal1() {
66 | let input = [8, 5, 1, 7, 10, 12]
67 | /**
68 | Tree structure
69 | 8
70 | / \
71 | 5 10
72 | / \ \
73 | 1 7 12
74 | */
75 | let expected = [
76 | 8,
77 | 5, 10,
78 | 1, 7, nil, 12
79 | ].convertToBinaryTree()
80 |
81 | let output = BinarySearchTree(root: sol24.bstFromPreorder(input))
82 | XCTAssertTrue(output.isEqualToOtherTree(expected))
83 | }
84 |
85 | func testConstructBSTFromPreorderTraversal2() {
86 | let input = [9, 5, 3, 8, 10, 15, 13, 19, 25]
87 | /**
88 | Tree structure
89 | 9
90 | / \
91 | 5 10
92 | / \ \
93 | 3 8 15
94 | / \
95 | 13 19
96 | \
97 | 25
98 | */
99 | let expected = [
100 | 9,
101 | 5, 10,
102 | 3, 8, nil, 15,
103 | nil, nil, nil, nil, nil, nil, 13, 19,
104 | nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 25
105 | ].convertToBinaryTree()
106 |
107 | let output = BinarySearchTree(root: sol24.bstFromPreorder(input))
108 | XCTAssertTrue(output.isEqualToOtherTree(expected))
109 | }
110 |
111 | // MARK: - Day 25: Uncrossed Lines
112 | func testMaxUncrossedLines1() {
113 | let input = (A: [1, 4, 2], B: [1, 2, 4])
114 | let expected = 2
115 | XCTAssertEqual(expected, sol25.maxUncrossedLines(input.A, input.B))
116 | }
117 |
118 | func testMaxUncrossedLines2() {
119 | let input = (A: [2, 5, 1, 2, 5], B: [10, 5, 2, 1, 5, 2])
120 | let expected = 3
121 | XCTAssertEqual(expected, sol25.maxUncrossedLines(input.A, input.B))
122 | }
123 |
124 | func testMaxUncrossedLines3() {
125 | let input = (A: [1, 3, 7, 1, 7, 5], B: [1, 9, 2, 5, 1])
126 | let expected = 2
127 | XCTAssertEqual(expected, sol25.maxUncrossedLines(input.A, input.B))
128 | }
129 |
130 | // MARK: - Day 26: Contiguous Array
131 | func testContiguousArray1() {
132 | let input = [0, 1]
133 | let expected = 2
134 | XCTAssertEqual(expected, sol26.findMaxLength(input))
135 | }
136 |
137 | func testContiguousArray2() {
138 | let input = [0, 1, 0]
139 | let expected = 2
140 | XCTAssertEqual(expected, sol26.findMaxLength(input))
141 | }
142 |
143 | func testContiguousArray3() {
144 | let input = [0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
145 | let expected = 8
146 | XCTAssertEqual(expected, sol26.findMaxLength(input))
147 | }
148 |
149 | func testContiguousArray4() {
150 | let input = [0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0]
151 | let expected = 12
152 | XCTAssertEqual(expected, sol26.findMaxLength(input))
153 | }
154 |
155 | // MARK: - Day 27: Possible Bipartition
156 | func testPossibleBipartition1() {
157 | let input = (N: 4, dislikes: [[1, 2], [1, 3], [2, 4]])
158 | XCTAssertTrue(sol27.possibleBipartition(input.N, input.dislikes))
159 | }
160 |
161 | func testPossibleBipartition2() {
162 | let input = (N: 3, dislikes: [[1, 2], [1, 3], [2, 3]])
163 | XCTAssertFalse(sol27.possibleBipartition(input.N, input.dislikes))
164 | }
165 |
166 | func testPossibleBipartition3() {
167 | let input = (N: 5, dislikes: [[1, 2], [2, 3], [3, 4], [4, 5], [1, 5]])
168 | XCTAssertFalse(sol27.possibleBipartition(input.N, input.dislikes))
169 | }
170 |
171 | // MARK: - Day 28: Counting Bits
172 | func testCountingBits1() {
173 | let input = 2
174 | let expected = [0, 1, 1]
175 | XCTAssertEqual(expected, sol28.countBits(input))
176 | }
177 |
178 | func testCountingBits2() {
179 | let input = 5
180 | let expected = [0, 1, 1, 2, 1, 2]
181 | XCTAssertEqual(expected, sol28.countBits(input))
182 | }
183 | }
184 |
185 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/ChallengeTests/TestsMayWeek5.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestsMayWeek5.swift
3 | // ChallengeTests
4 | //
5 | // Created by Michael Ho on 6/3/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class TestsMayWeek5: XCTestCase {
12 | let sol29 = MaySolDay29()
13 | let sol30 = MaySolDay30()
14 | let sol31 = MaySolDay31()
15 |
16 | // MARK: - Day 29: Course Schedule
17 | func testCourseSchedule1() {
18 | let input = (numCourses: 2, prerequisites: [[1, 0]])
19 | XCTAssertTrue(sol29.canFinish(input.numCourses, input.prerequisites))
20 | }
21 |
22 | func testCourseSchedule2() {
23 | let input = (numCourses: 2, prerequisites: [[1, 0], [0, 1]])
24 | XCTAssertFalse(sol29.canFinish(input.numCourses, input.prerequisites))
25 | }
26 |
27 | func testCourseSchedule3() {
28 | let input = (numCourses: 8, prerequisites: [[1, 0], [2, 6], [1, 7], [6, 4], [7, 0], [0, 5], [7, 6]])
29 | XCTAssertTrue(sol29.canFinish(input.numCourses, input.prerequisites))
30 | }
31 |
32 | func testCourseSchedule4() {
33 | let input = (numCourses: 4, prerequisites: [[1, 0], [2, 0], [3, 1], [3, 2], [1, 3]])
34 | XCTAssertFalse(sol29.canFinish(input.numCourses, input.prerequisites))
35 | }
36 |
37 | // MARK: - Day 30: K Closest Points to Origin
38 | func testKClosest1() {
39 | let input = (points: [[1, 3], [-2, 2]], K: 1)
40 | let expected = [[-2, 2]]
41 | XCTAssertEqual(expected, sol30.kClosest(input.points, input.K))
42 | }
43 |
44 | func testKClosest2() {
45 | let input = (points: [[3, 3], [5, -1], [-2, 4]], K: 2)
46 | let expected = [[3, 3], [-2, 4]]
47 | XCTAssertEqual(expected, sol30.kClosest(input.points, input.K))
48 | }
49 |
50 | // MARK: - Day 31: Edit Distance
51 | func testEditDistance1() {
52 | let input = (word1: "horse", word2: "ros")
53 | let expected = 3
54 | XCTAssertEqual(expected, sol31.minDistance(input.word1, input.word2))
55 | }
56 |
57 | func testEditDistance2() {
58 | let input = (word1: "intention", word2: "execution")
59 | let expected = 5
60 | XCTAssertEqual(expected, sol31.minDistance(input.word1, input.word2))
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge.xcodeproj/xcshareddata/xcschemes/LeetCodeChallenge.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay1.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay1.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/single-number/
10 | class AprilSolDay1 {
11 |
12 | func singleNumber(_ nums: [Int]) -> Int {
13 | var dict = [Int:Bool]()
14 | for num in nums {
15 | if (dict[num] != nil) {
16 | dict[num] = false
17 | } else {
18 | dict[num] = true
19 | }
20 | }
21 |
22 | for key in dict.keys {
23 | if (dict[key] != false) {
24 | return key
25 | }
26 | }
27 |
28 | return -1
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay2.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay2.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/happy-number/
10 | class AprilSolDay2 {
11 |
12 | func isHappy(_ n: Int) -> Bool {
13 | var set = Set()
14 | var current = n
15 | while current > 0, !set.contains(current) {
16 | current = operateHappyNum(current, &set)
17 | }
18 | return current == 1
19 | }
20 |
21 | func operateHappyNum(_ num: Int, _ set: inout Set) -> Int {
22 | var num = num
23 | while (num % 10 == 0) {
24 | num = num / 10
25 | }
26 | set.insert(num)
27 |
28 | var sum = 0
29 | while (num > 0) {
30 | let last = num % 10
31 | sum += last * last
32 | num = num / 10
33 | }
34 | return sum
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay3.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay3.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/maximum-subarray/
10 | class AprilSolDay3 {
11 |
12 | func maxSubArray(_ nums: [Int]) -> Int {
13 | guard nums.count > 0 else { return 0 }
14 |
15 | if nums.count == 1 {
16 | return nums[0]
17 | }
18 |
19 | var localMax = nums[0]
20 | var result = localMax
21 | for idx in 1...nums.count - 1 {
22 | localMax = max(nums[idx] + localMax, nums[idx])
23 | result = max(localMax, result)
24 | }
25 | return result
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay4.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay4.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/move-zeroes/
10 | class AprilSolDay4 {
11 |
12 | func moveZeroes(_ nums: inout [Int]) {
13 | var idx = 0
14 | var count = 0
15 | while idx < nums.count, count < nums.count {
16 | if nums[idx] == 0 {
17 | nums.remove(at: idx)
18 | nums.append(0)
19 | } else {
20 | idx += 1
21 | }
22 | count += 1
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay5.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay5.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/
10 | class AprilSolDay5 {
11 |
12 | func maxProfit(_ prices: [Int]) -> Int {
13 | guard prices.count > 1 else { return 0 }
14 |
15 | var preVal = prices[0]
16 | var val = 0
17 | for idx in 1...prices.count-1 {
18 | if prices[idx] > preVal {
19 | val += prices[idx] - preVal
20 | }
21 | preVal = prices[idx]
22 | }
23 | return val
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay6.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay6.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // https://leetcode.com/problems/group-anagrams/
10 | class AprilSolDay6 {
11 |
12 | func groupAnagrams(_ strs: [String]) -> [[String]] {
13 | var dict = [String:[String]]()
14 | for str in strs {
15 | let key = String(str.sorted())
16 | if dict[key] != nil {
17 | dict[key]!.append(str)
18 | } else {
19 | dict[key] = [str]
20 | }
21 | }
22 | var output = [[String]]()
23 | for key in dict.keys {
24 | output.append(dict[key]!)
25 | }
26 | return output
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay7.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay7.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/explore/featured/card/30-day-leetcoding-challenge/528/week-1/3289/
10 | class AprilSolDay7 {
11 |
12 | func countElements(_ arr: [Int]) -> Int {
13 | let set = Set(arr)
14 | var output = 0
15 | for num in arr {
16 | if set.contains(num + 1) {
17 | output += 1
18 | }
19 | }
20 | return output
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay10.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay10.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/15/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/min-stack/
10 | class AprilSolDay10 {
11 |
12 | class MinStack: MinStackProtocol {
13 | var stack: [Node]
14 |
15 | /** initialize your data structure here. */
16 | init() {
17 | stack = [Node]()
18 | }
19 |
20 | func push(_ x: Int) {
21 | stack.append(Node(x, min(x, getMin())))
22 | }
23 |
24 | func pop() {
25 | stack.removeLast()
26 | }
27 |
28 | func top() -> Int {
29 | guard let last = stack.last else { return -1 }
30 | return last.val
31 | }
32 |
33 | func getMin() -> Int {
34 | guard let last = stack.last else { return Int.max }
35 | return last.minVal
36 | }
37 | }
38 |
39 | class Node {
40 | var val: Int
41 | var minVal: Int
42 |
43 | init(_ value: Int, _ minVal: Int) {
44 | self.val = value
45 | self.minVal = minVal
46 | }
47 | }
48 | }
49 |
50 | protocol MinStackProtocol {
51 | // Push element x onto stack.
52 | func push(_ x: Int)
53 | // Removes the element on top of the stack.
54 | func pop()
55 | // Get the top element.
56 | func top() -> Int
57 | // Retrieve the minimum element in the stack.
58 | func getMin() -> Int
59 | }
60 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay11.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay11.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/15/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/diameter-of-binary-tree/
10 | class AprilSolDay11 {
11 |
12 | func diameterOfBinaryTree(_ root: TreeNode?) -> Int {
13 | guard let root = root else { return 0 }
14 |
15 | var output = 0
16 | let _ = calculateLocalMaxLength(root, &output)
17 | return output - 1
18 | }
19 | /**
20 | This function solves the problem of calculating the longest one-way
21 | length that associated with a tree node. Let's define a leg as the
22 | one-way path that does not pass the root.
23 |
24 | - Parameter root: The root node to start with.
25 | - Parameter output: The output tracks the longest path in the entire tree.
26 | */
27 | func calculateLocalMaxLength(_ root: TreeNode?, _ output: inout Int) -> Int {
28 | guard let root = root else { return 0 }
29 |
30 | // A local longest path is calculcated by adding up its longest left and right legs.
31 | let left = calculateLocalMaxLength(root.left, &output)
32 | let right = calculateLocalMaxLength(root.right, &output)
33 | let localLongestPath = left + right + 1
34 |
35 | // This helps obtain the longest path of the tree by comparing each caculation.
36 | output = max(output, localLongestPath)
37 |
38 | // A leg is caclulated by adding itself to its longer leg.
39 | // Note: The leg is defined to not pass its root node.
40 | return 1 + max(left, right)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay12.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay12.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/15/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/last-stone-weight/
10 | class AprilSolDay12 {
11 | /*
12 | Note:
13 |
14 | 1. 1 <= stones.length <= 30
15 | 2. 1 <= stones[i] <= 1000
16 | */
17 | func lastStoneWeight(_ stones: [Int]) -> Int {
18 | var sorted = stones.sorted()
19 |
20 | while sorted.count > 1 {
21 | let last1 = sorted.removeLast()
22 | let last2 = sorted.removeLast()
23 |
24 | if last1 != last2 {
25 | sorted.append(last1 - last2)
26 | sorted.sort()
27 | }
28 | }
29 |
30 | return sorted.count > 0 ? sorted[0] : 0
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay13.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay13.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/15/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/contiguous-array/
10 | class AprilSolDay13 {
11 |
12 | func findMaxLength(_ nums: [Int]) -> Int {
13 | /**
14 | The count before we enter the array is 0. The index
15 | before we enter the array is noted as -1.
16 | */
17 | var dict = [0 : -1] // [count:index]
18 | var count = 0
19 |
20 | // The maximum length (longest) is set to 0 initially.
21 | var maxLength = 0
22 | for idx in 0.. String {
22 | var totalShift = 0
23 | for move in shift {
24 | if move[0] == 0 {
25 | totalShift -= move[1]
26 | } else if move[0] == 1 {
27 | totalShift += move[1]
28 | }
29 | }
30 | var output = Array(s)
31 | totalShift = totalShift%s.count
32 | if totalShift > 0 {
33 | output = Array(output[output.count - totalShift.. SinglyListNode? {
13 | guard head != nil else { return nil }
14 |
15 | var slowNode: SinglyListNode? = head
16 | var fastNode: SinglyListNode? = head
17 |
18 | while fastNode?.next != nil {
19 | slowNode = slowNode?.next
20 | fastNode = fastNode?.next?.next
21 | }
22 |
23 | return slowNode
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay9.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay9.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/15/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/backspace-string-compare/
10 | class AprilSolDay9 {
11 |
12 | func backspaceCompare(_ S: String, _ T: String) -> Bool {
13 | return formatString(S) == formatString(T)
14 | }
15 |
16 | func formatString(_ s: String) -> String {
17 | let arr = Array(s)
18 | var output = ""
19 | var back = 0
20 | for idx in 0.. 0{
26 | back -= 1
27 | } else {
28 | output += String(arr[lastIdx])
29 | }
30 | }
31 | }
32 | return output
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay15.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay15.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/20/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/product-of-array-except-self/
10 | class AprilSolDay15 {
11 |
12 | func productExceptSelf(_ nums: [Int]) -> [Int] {
13 | var foundFirstZero = false
14 | var total = 1
15 | for num in nums {
16 | if !foundFirstZero && num == 0 {
17 | foundFirstZero = true
18 | } else {
19 | total = total * num
20 | }
21 | }
22 |
23 | var output = [Int]()
24 | if foundFirstZero && total == 0 {
25 | return Array(repeating: 0, count: nums.count)
26 | }
27 |
28 | for num in nums {
29 | if foundFirstZero {
30 | if num == 0 {
31 | output.append(total)
32 | } else {
33 | output.append(0)
34 | }
35 | } else {
36 | output.append(total/num)
37 | }
38 | }
39 | return output
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay16.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay16.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/20/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/valid-parenthesis-string/
10 | // Refer to LeiHao0: https://leetcode.com/problems/valid-parenthesis-string/discuss/582051/Swift-0ms-100-or-1line-94.44
11 | class AprilSolDay16 {
12 |
13 | func checkValidString(_ s: String) -> Bool {
14 | var stack = [Character]()
15 | for c in s {
16 | if c == "(" || c == "*" {
17 | stack.append(c)
18 | } else {
19 | if let idx = stack.lastIndex(of: "(") {
20 | stack.remove(at: idx)
21 | } else if let idx = stack.lastIndex(of: "*") {
22 | stack.remove(at: idx)
23 | } else {
24 | return false
25 | }
26 | }
27 | }
28 |
29 | // popLast() time complexity = O(1)
30 | while let last = stack.popLast() {
31 | if last == "(" {
32 | return false
33 | } else if let leftIdx = stack.lastIndex(of: "(") {
34 | stack.remove(at: leftIdx)
35 | }
36 | }
37 | return stack.isEmpty
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay17.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay17.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/21/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/number-of-islands/
10 | class AprilSolDay17 {
11 |
12 | func numIslands(_ grid: [[Character]]) -> Int {
13 | var count = 0
14 | var matrix = grid
15 | for x in 0..= 0, matrix[x][y - 1] == "1" {
38 | findAdjacentIslands(x, y - 1, &matrix)
39 | }
40 |
41 | if x - 1 >= 0, matrix[x - 1][y] == "1" {
42 | findAdjacentIslands(x - 1, y, &matrix)
43 | }
44 | }
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay18.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay18.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/21/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/minimum-path-sum/
10 | class AprilSolDay18 {
11 |
12 | func minPathSum(_ grid: [[Int]]) -> Int {
13 | var matrix = grid
14 |
15 | for i in 0.. 0 && j > 0 {
18 | matrix[i][j] += min(matrix[i-1][j], matrix[i][j-1])
19 | } else if i > 0 {
20 | matrix[i][j] += matrix[i-1][j]
21 | } else if j > 0 {
22 | matrix[i][j] += matrix[i][j-1]
23 | }
24 | }
25 | }
26 |
27 | return matrix[matrix.count - 1][matrix[0].count - 1]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay19.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay19.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/21/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/search-in-rotated-sorted-array/
10 | // The solution's runtime complexity must be in the order of O(log n).
11 | class AprilSolDay19 {
12 |
13 | func search(_ nums: [Int], _ target: Int) -> Int {
14 | guard nums.count > 0 else { return -1 }
15 |
16 | var start = 0
17 | var end = nums.count - 1
18 | while start <= end {
19 | let mid = start + (end - start) / 2
20 | let midVal = nums[mid]
21 |
22 | if target == midVal {
23 | return mid
24 | } else if target == nums[start] {
25 | return start
26 | } else if target == nums[end] {
27 | return end
28 | } else if midVal > nums[start] {
29 | // If it falls into this condition, it means the first half of
30 | // the array is not rotated. Therefore, we can decide if the
31 | // target falls into the first half or not.
32 | if target < midVal, target > nums[start] {
33 | end = mid - 1
34 | } else {
35 | start = mid + 1
36 | }
37 | } else {
38 | // If it falls into this condition, it means the second half of
39 | // the array is not rotated. Therefore, we can decide if the
40 | // target falls into the second half or not.
41 | if target > midVal, target < nums[end] {
42 | start = mid + 1
43 | } else {
44 | end = mid - 1
45 | }
46 | }
47 | }
48 |
49 | return -1
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay20.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay20.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/21/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/
10 | class AprilSolDay20 {
11 |
12 | func bstFromPreorder(_ preorder: [Int]) -> TreeNode? {
13 | guard preorder.count > 0 else { return nil }
14 | return bstFromPreorder(preorder, 0, preorder.count - 1)
15 | }
16 |
17 | private func bstFromPreorder(_ preorder: [Int], _ start: Int, _ end: Int) -> TreeNode? {
18 | let root = TreeNode(preorder[start])
19 |
20 | if start + 1 <= end, preorder.count > 1 {
21 | var rightRootIdx = -1
22 | for idx in start+1...end {
23 | if preorder[idx] > preorder[start] {
24 | rightRootIdx = idx
25 | break
26 | }
27 | }
28 |
29 | if rightRootIdx == start + 1 {
30 | root.right = bstFromPreorder(preorder, rightRootIdx, end)
31 | } else if rightRootIdx == -1 {
32 | root.left = bstFromPreorder(preorder, start + 1, end)
33 | } else {
34 | root.right = bstFromPreorder(preorder, rightRootIdx, end)
35 | root.left = bstFromPreorder(preorder, start + 1, rightRootIdx - 1)
36 | }
37 | }
38 | return root
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay21.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay21.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/21/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/explore/featured/card/30-day-leetcoding-challenge/530/week-3/3306/
10 | class AprilSolDay21 {
11 |
12 | func leftMostColumnWithOne(_ binaryMatrix: BinaryMatrix) -> Int {
13 | let dim = binaryMatrix.dimensions()
14 |
15 | var x = 0
16 | var y = dim[1] - 1
17 | var currentLeftMost = -1
18 | while x < dim[0], y >= 0 {
19 | if y - 1 >= 0 && binaryMatrix.get(x, y - 1) == 1 {
20 | y -= 1
21 | currentLeftMost = y
22 | } else if x + 1 < dim[0] {
23 | x += 1
24 | } else {
25 | return binaryMatrix.get(x, y) == 1 ? y : currentLeftMost
26 | }
27 | }
28 | return -1
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay22.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay22.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/27/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/subarray-sum-equals-k/
10 | class AprilSolDay22 {
11 |
12 | func subarraySum(_ nums: [Int], _ k: Int) -> Int {
13 | var output = 0
14 | var dict = [0:1] // [sum:count]
15 |
16 | var sum = 0
17 | for num in nums {
18 | sum += num
19 |
20 | /**
21 | Let's define prevSum = sum - k
22 | If sum is larger than target k, try to find if sum - k has
23 | occurred in the iteration. If it has, retrieve the times when
24 | sum == prevSum. Since we can exclude those subarrays that have
25 | a sum of prevSum, the count of subarray has target k can be
26 | increased by the count of those subarrays.
27 | */
28 | if let count = dict[sum - k] {
29 | output += count
30 | }
31 |
32 | dict[sum] = (dict[sum] ?? 0) + 1
33 | }
34 |
35 | return output
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay23.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay23.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/27/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/bitwise-and-of-numbers-range/
10 | // https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html
11 | class AprilSolDay23 {
12 |
13 | func rangeBitwiseAnd(_ m: Int, _ n: Int) -> Int {
14 | if m == 0 {
15 | return 0
16 | }
17 |
18 | var m = m
19 | var n = n
20 | var factor = 0
21 |
22 | while m != n {
23 | m >>= 1
24 | n >>= 1
25 | factor += 1
26 | }
27 |
28 | return m << factor
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay24.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay24.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/27/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/lru-cache/
10 |
11 | class AprilSolDay24 {
12 |
13 | class LRUCache {
14 |
15 | var capacity: Int
16 | var head: ListNode
17 | var tail: ListNode
18 | var dict: [Int:ListNode]
19 |
20 | init(_ capacity: Int) {
21 | self.capacity = capacity
22 | dict = [Int:ListNode]()
23 |
24 | head = ListNode(-1, -1)
25 | tail = ListNode(-1, -1)
26 | head.next = tail
27 | tail.prev = head
28 | }
29 |
30 | func get(_ key: Int) -> Int {
31 | if let node = dict[key] {
32 | remove(node)
33 | insertToHead(node)
34 | return node.val
35 | }
36 | return -1
37 | }
38 |
39 | func insertToHead(_ node: ListNode) {
40 | node.next = head.next
41 | head.next?.prev = node
42 | head.next = node
43 | node.prev = head
44 | }
45 |
46 | func remove(_ node: ListNode) {
47 | node.next?.prev = node.prev
48 | node.prev?.next = node.next
49 | }
50 |
51 | func put(_ key: Int, _ value: Int) {
52 | let node = ListNode(value, key)
53 |
54 | if dict[key] != nil {
55 | remove(dict[key]!)
56 | } else if dict.keys.count == capacity {
57 | if let lastNode = tail.prev {
58 | remove(lastNode)
59 | dict[lastNode.key] = nil
60 | }
61 | }
62 |
63 | dict[key] = node
64 | insertToHead(node)
65 | }
66 | }
67 |
68 | class ListNode {
69 | var val: Int
70 | var key: Int
71 | var next: ListNode?
72 | var prev: ListNode?
73 |
74 | init(_ val: Int, _ key: Int) {
75 | self.val = val
76 | self.key = key
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay25.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay25.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/27/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/jump-game/
10 | class AprilSolDay25 {
11 |
12 | func canJump(_ nums: [Int]) -> Bool {
13 | guard nums.count > 1 else { return true }
14 |
15 | var idx = 0
16 | var maxJump = 0
17 | while idx < nums.count {
18 | if idx > maxJump {
19 | return false
20 | }
21 | maxJump = max(maxJump, nums[idx] + idx)
22 | idx += 1
23 | }
24 | return true
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay26.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay26.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/longest-common-subsequence/
10 | class AprilSolDay26 {
11 |
12 | func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
13 | guard text1.count > 0, text2.count > 0 else { return 0 }
14 |
15 | let arr1 = Array(text1)
16 | let arr2 = Array(text2)
17 | var dp = Array(repeating: Array(repeating: 0, count: arr2.count), count: arr1.count)
18 | for i in 0.. 0, j > 0 {
24 | dp[idx1][idx2] += dp[idx1 + 1][idx2 + 1]
25 | }
26 | dp[idx1][idx2] += 1
27 | } else {
28 | let accum1 = i > 0 ? dp[idx1 + 1][idx2] : 0
29 | let accum2 = j > 0 ? dp[idx1][idx2 + 1] : 0
30 | dp[idx1][idx2] += max(accum1, accum2)
31 | }
32 | }
33 | }
34 | return dp[0][0]
35 | }
36 | }
37 |
38 | // Recursive solution: easy to understand, exceeds the time limit though.
39 | class RescursiveSolution {
40 |
41 | func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
42 | return longestCommonSubsequence(Array(text1), Array(text2), 0, 0)
43 | }
44 |
45 | func longestCommonSubsequence(_ arr1: [Character], _ arr2: [Character], _ idx1: Int, _ idx2: Int) -> Int {
46 | if idx1 >= arr1.count || idx2 >= arr2.count {
47 | return 0
48 | }
49 |
50 | if arr1[idx1] == arr2[idx2] {
51 | return 1 + longestCommonSubsequence(arr1, arr2, idx1 + 1, idx2 + 1)
52 | } else {
53 | return max(longestCommonSubsequence(arr1, arr2, idx1, idx2 + 1), longestCommonSubsequence(arr1, arr2, idx1 + 1, idx2))
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay27.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay27.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/maximal-square/
10 | class AprilSolDay27 {
11 |
12 | func maximalSquare(_ matrix: [[Character]]) -> Int {
13 | guard matrix.count > 0, matrix[0].count > 0 else { return 0 }
14 | var dp = Array(repeating: Array(repeating: 0, count: matrix[0].count), count: matrix.count)
15 | var maxSideLength = 0
16 | for x in 0.. 0, y > 0 {
20 | dp[x][y] = min(dp[x - 1][y - 1], dp[x - 1][y], dp[x][y - 1] ) + 1
21 | } else {
22 | dp[x][y] = Int(String(matrix[x][y]))!
23 | }
24 | maxSideLength = max(maxSideLength, dp[x][y])
25 | }
26 | }
27 | }
28 | return maxSideLength*maxSideLength
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay28.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay28.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/explore/featured/card/30-day-leetcoding-challenge/531/week-4/3313/
10 | class AprilSolDay28 {
11 |
12 | class FirstUnique: FirstUniqueProtocol {
13 | var dict: [Int:DoublyListNode]
14 | var head: DoublyListNode
15 | var tail: DoublyListNode
16 |
17 | required init(_ nums: [Int]) {
18 | dict = [Int:DoublyListNode]()
19 |
20 | head = DoublyListNode(-1)
21 | tail = DoublyListNode(-1)
22 | head.next = tail
23 | tail.prev = head
24 |
25 | for num in nums {
26 | add(num)
27 | }
28 | }
29 |
30 | func appendNode(_ node: DoublyListNode) {
31 | tail.prev?.next = node
32 | node.next = tail
33 | node.prev = tail.prev
34 | tail.prev = node
35 | }
36 |
37 | func removeNode(_ node: DoublyListNode) {
38 | node.next?.prev = node.prev
39 | node.prev?.next = node.next
40 | }
41 |
42 | func showFirstUnique() -> Int {
43 | if let node = head.next {
44 | return node.val
45 | }
46 | return -1
47 | }
48 |
49 | func add(_ value: Int) {
50 | if dict[value] != nil {
51 | removeNode(dict[value]!)
52 | dict[value] = DoublyListNode(-1)
53 | } else {
54 | let newNode = DoublyListNode(value)
55 | appendNode(newNode)
56 | dict[value] = newNode
57 | }
58 | }
59 | }
60 | }
61 |
62 | protocol FirstUniqueProtocol {
63 | // Initializes the object with the numbers in the queue
64 | init(_ nums: [Int])
65 | // Returns the value of the first unique integer of the queue, and
66 | // returns -1 if there is no such integer.
67 | func showFirstUnique() -> Int
68 | // Insert the value to the queue.
69 | func add(_ val: Int)
70 | }
71 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek5/SolutionDay29.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay29.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/1/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/binary-tree-maximum-path-sum/
10 | /**
11 | Subproblems:
12 |
13 | 1. How to calculate a one-way path that has the largest value?
14 | Let's define a leg as the one-way path that does not pass the
15 | local root, which is the starting nodepassed to the recursion.
16 |
17 | 2. How to find the local max-value path of a node?
18 | It consists of up to two non-overlapping legs since it may or may
19 | not pass the root. That said, legs that share the same root may not
20 | be included simultaneously.
21 |
22 | 3. How to find the max-value path of the entire tree?
23 | It will be obtained by comparing the local max-value paths.
24 | */
25 | class AprilSolDay29 {
26 |
27 | func maxPathSum(_ root: TreeNode?) -> Int {
28 | guard let root = root else { return 0 }
29 |
30 | var output = Int.min
31 | let _ = getSum(root, &output)
32 | return output
33 | }
34 |
35 | private func getSum(_ root: TreeNode?, _ output: inout Int) -> Int {
36 | guard let root = root else { return 0 }
37 |
38 | var leftSum = 0
39 | var rightSum = 0
40 | if let left = root.left {
41 | leftSum = getSum(left, &output)
42 | }
43 |
44 | if let right = root.right {
45 | rightSum = getSum(right, &output)
46 | }
47 |
48 | let largestLegValue = max(root.val + leftSum, root.val + rightSum, root.val)
49 |
50 | /**
51 | This comparison is trying to find the local maximum value staring from
52 | the local root node.
53 | */
54 | let localMaxValue = max(root.val + rightSum + leftSum, largestLegValue)
55 |
56 | /**
57 | The comparison here is trying to get the final output, which is the
58 | max-value path of the entire tree.
59 | */
60 | output = max(output, localMaxValue)
61 |
62 | /**
63 | The return value here is the leg value, aka the one-way path that has the largest
64 | value. Because there might be negative values in the legs, we have to first decide
65 | if we want to include a leg value. If we do, we want to take the leg with larger value.
66 | */
67 | return largestLegValue
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/AprilWeek5/SolutionDay30.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AprilSolDay30.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/1/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 |
10 | // Original link is blocked. Refer to other developer's blog.
11 | // https://thefellowprogrammer.blogspot.com/2020/04/check-if-string-is-valid-sequence-from.html
12 | class AprilSolDay30 {
13 |
14 | func isValidSequence(_ root: TreeNode?, _ arr: [Int]) -> Bool {
15 | var current = [Int]()
16 | return isValidSequence(root, ¤t, arr)
17 | }
18 |
19 | private func isValidSequence(_ root: TreeNode?, _ current: inout [Int], _ target: [Int]) -> Bool {
20 | guard let root = root else {
21 | return false
22 | }
23 |
24 | current.append(root.val)
25 | if let left = root.left, let right = root.right {
26 | return isValidSequence(left, ¤t, target) || isValidSequence(right, ¤t, target)
27 | } else if let left = root.left {
28 | return isValidSequence(left, ¤t, target)
29 | } else if let right = root.right {
30 | return isValidSequence(right, ¤t, target)
31 | } else {
32 | return current == target
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay1.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay1.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/3/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/first-bad-version/
10 | class MaySolDay1 {
11 | private var badVersion = 0
12 |
13 | func firstBadVersion(_ n: Int) -> Int {
14 | if n == 1 {
15 | return isBadVersion(n) ? 1 : -1
16 | }
17 | var start = 1
18 | var end = n
19 | while start < end {
20 | let mid = (start + end) / 2
21 | if end == start + 1 {
22 | return isBadVersion(start) ? start : end
23 | }
24 | if isBadVersion(mid) {
25 | end = mid
26 | } else {
27 | start = mid
28 | }
29 | }
30 | return -1
31 | }
32 |
33 | func setBadVersion(_ version: Int) {
34 | self.badVersion = version
35 | }
36 |
37 | private func isBadVersion(_ version: Int) -> Bool {
38 | return version == self.badVersion
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay2.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay2.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/3/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/jewels-and-stones/
10 | class MaySolDay2 {
11 |
12 | func numJewelsInStones(_ J: String, _ S: String) -> Int {
13 | var set = Set()
14 | for ch in J {
15 | set.insert(ch)
16 | }
17 |
18 | var output = 0
19 | for ch in S {
20 | if set.contains(ch) {
21 | output += 1
22 | }
23 | }
24 |
25 | return output
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay3.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay3.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/7/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/ransom-note/
10 | class MaySolDay3 {
11 |
12 | func canConstruct(_ ransomNote: String, _ magazine: String) -> Bool {
13 | var dict = [Character:Int]()
14 | for ch in magazine {
15 | if dict[ch] == nil {
16 | dict[ch] = 1
17 | } else {
18 | dict[ch]! += 1
19 | }
20 | }
21 |
22 | for ch in ransomNote {
23 | if dict[ch] == nil {
24 | return false
25 | } else {
26 | dict[ch]! -= 1
27 | if dict[ch]! == 0 {
28 | dict[ch] = nil
29 | }
30 | }
31 | }
32 |
33 | return true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay4.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay4.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/7/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/number-complement/
10 | class MaySolDay4 {
11 |
12 | func findComplement(_ num: Int) -> Int {
13 | var i = 1
14 |
15 | while i <= num {
16 | i <<= 1
17 | }
18 |
19 | return (i - 1) ^ num
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay5.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay5.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/7/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/first-unique-character-in-a-string/
10 | class MaySolDay5 {
11 |
12 | func firstUniqChar(_ s: String) -> Int {
13 | var dict = [Character : DoublyListNode]()
14 | let head = DoublyListNode(-1)
15 | let tail = DoublyListNode(-1)
16 | head.next = tail
17 | tail.prev = head
18 |
19 | for (idx, ch) in s.enumerated() {
20 | if dict[ch] == nil {
21 | let node = DoublyListNode(idx)
22 | dict[ch] = node
23 | appendNode(tail, node)
24 | } else if dict[ch]!.val == -1 {
25 | continue
26 | } else {
27 | removeNode(dict[ch]!)
28 | }
29 | }
30 |
31 | return head.next!.val == -1 ? -1 : head.next!.val
32 | }
33 |
34 | private func appendNode(_ tail: DoublyListNode, _ node: DoublyListNode) {
35 | tail.prev?.next = node
36 | node.prev = tail.prev
37 | tail.prev = node
38 | node.next = tail
39 | }
40 |
41 | private func removeNode(_ node: DoublyListNode) {
42 | node.prev?.next = node.next
43 | node.next?.prev = node.prev
44 | node.prev = nil
45 | node.next = nil
46 | node.val = -1
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay6.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay6.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/11/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/majority-element/
10 | class MaySolDay6 {
11 |
12 | func majorityElement(_ nums: [Int]) -> Int {
13 | var dict = [Int:Int]()
14 |
15 | for num in nums {
16 | if dict[num] == nil {
17 | dict[num] = 1
18 | } else {
19 | dict[num]! += 1
20 | }
21 |
22 | if dict[num]! > nums.count/2 {
23 | return num
24 | }
25 | }
26 |
27 | return -1
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay7.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay7.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/11/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/cousins-in-binary-tree/
10 | class MaySolDay7 {
11 |
12 | func isCousins(_ root: TreeNode?, _ x: Int, _ y: Int) -> Bool {
13 | guard let root = root else { return false }
14 |
15 | var setArr = [Set]()
16 | return findCousins(root, 0, x, y, &setArr)
17 | }
18 |
19 | private func findCousins(_ root: TreeNode?, _ level: Int, _ x: Int, _ y: Int, _ setArr: inout [Set]) -> Bool {
20 | guard let root = root else { return false }
21 |
22 | if level >= setArr.count {
23 | let set = Set([root.val])
24 | setArr.append(set)
25 | } else {
26 | setArr[level].insert(root.val)
27 | }
28 |
29 | if (root.left?.val == x && root.right?.val == y) ||
30 | (root.left?.val == y && root.right?.val == x) {
31 | return false
32 | } else if setArr[level].contains(x), setArr[level].contains(y) {
33 | print("b")
34 | return true
35 | } else {
36 | return findCousins(root.left, level + 1, x, y, &setArr) || findCousins(root.right, level + 1, x, y, &setArr)
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay10.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay10.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/21/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/find-the-town-judge/
10 | class MaySolDay10 {
11 |
12 | func findJudge(_ N: Int, _ trust: [[Int]]) -> Int {
13 | if N == 1, trust.count == 0 {
14 | return 1
15 | }
16 |
17 | var dict = [Int:Set]()
18 | var nojudges = Set()
19 | var judge = -1
20 | for arr in trust {
21 | nojudges.insert(arr[0])
22 | if dict[arr[1]] == nil {
23 | dict[arr[1]] = Set([arr[0]])
24 | } else {
25 | dict[arr[1]]!.insert(arr[0])
26 | }
27 |
28 | if dict[arr[1]]!.count == N - 1 {
29 | judge = arr[1]
30 | }
31 | }
32 |
33 | return !nojudges.contains(judge) ? judge : -1
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay11.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay11.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/flood-fill/
10 | class MaySolDay11 {
11 |
12 | func floodFill(_ image: [[Int]], _ sr: Int, _ sc: Int, _ newColor: Int) -> [[Int]] {
13 | var newImg = image
14 | let oldColor = image[sr][sc]
15 | dfs(sr, sc, &newImg, newColor, oldColor)
16 | return newImg
17 | }
18 |
19 | private func dfs(_ x: Int, _ y: Int, _ image: inout [[Int]], _ newColor: Int, _ oldColor: Int) {
20 | if image[x][y] != oldColor {
21 | return
22 | }
23 | image[x][y] = newColor
24 |
25 | if x + 1 < image.count, image[x + 1][y] != newColor {
26 | dfs(x + 1, y, &image, newColor, oldColor)
27 | }
28 |
29 | if y + 1 < image[x].count, image[x][y + 1] != newColor {
30 | dfs(x, y + 1, &image, newColor, oldColor)
31 | }
32 |
33 | if x - 1 >= 0, image[x - 1][y] != newColor {
34 | dfs(x - 1, y, &image, newColor, oldColor)
35 | }
36 |
37 | if y - 1 >= 0, image[x][y - 1] != newColor {
38 | dfs(x, y - 1, &image, newColor, oldColor)
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay12.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay12.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/single-element-in-a-sorted-array/
10 | class MaySolDay12 {
11 |
12 | func singleNonDuplicate(_ nums: [Int]) -> Int {
13 | var set = Set()
14 | for num in nums {
15 | if set.contains(num) {
16 | set.remove(num)
17 | } else {
18 | set.insert(num)
19 | }
20 | }
21 | return set.removeFirst()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay13.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay13.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/remove-k-digits/
10 | class MaySolDay13 {
11 |
12 | func removeKdigits(_ num: String, _ k: Int) -> String {
13 | guard num.count > 0 && k < num.count else { return "0" }
14 |
15 | let arr = Array(num)
16 | var stackChar = [Character]()
17 | var count = k
18 | var i = 0
19 | while i < arr.count {
20 | // Pop the elements if they are not in the increasing order
21 | while count > 0, let last = stackChar.last, last > arr[i] {
22 | stackChar.removeLast()
23 | count -= 1
24 | }
25 | stackChar.append(arr[i])
26 | i += 1
27 | }
28 |
29 | while count > 0 {
30 | stackChar.removeLast()
31 | count -= 1
32 | }
33 |
34 | // Find leading 0s
35 | while let first = stackChar.first, first == "0" {
36 | stackChar.removeFirst()
37 | }
38 |
39 | return stackChar.isEmpty ? "0" : String(stackChar)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay14.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay14.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/14/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/implement-trie-prefix-tree/
10 | class MaySolDay14 {
11 |
12 | class Trie: TrieProtocol {
13 | let root: TrieNode
14 |
15 | required init() {
16 | root = TrieNode(Character("0"))
17 | }
18 |
19 | func insert(_ word: String) {
20 | var node = root
21 | for ch in word {
22 | if node.children[ch] == nil {
23 | node.children[ch] = TrieNode(ch)
24 | }
25 | node = node.children[ch]!
26 | }
27 |
28 | node.children[Character("0")] = TrieNode(Character("0"))
29 | }
30 |
31 | func search(_ word: String) -> Bool {
32 | var node = root
33 | for ch in word {
34 | if node.children[ch] != nil {
35 | node = node.children[ch]!
36 | } else {
37 | return false
38 | }
39 | }
40 | return node.children[Character("0")] != nil
41 | }
42 |
43 | func startsWith(_ prefix: String) -> Bool {
44 | var node = root
45 | for ch in prefix {
46 | if node.children[ch] != nil {
47 | node = node.children[ch]!
48 | } else {
49 | return false
50 | }
51 | }
52 | return true
53 | }
54 | }
55 |
56 | class TrieNode {
57 | var char: Character
58 | var children = [Character : TrieNode]()
59 |
60 | init(_ char: Character) {
61 | self.char = char
62 | }
63 | }
64 | }
65 |
66 | protocol TrieProtocol {
67 | // Initialize your data structure here.
68 | init()
69 | // Inserts a word into the trie.
70 | func insert(_ word: String)
71 | // Returns if the word is in the trie.
72 | func search(_ word: String) -> Bool
73 | // Returns if there is any word in the trie that starts with the given prefix
74 | func startsWith(_ prefix: String) -> Bool
75 | }
76 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay8.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay8.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/21/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/check-if-it-is-a-straight-line/
10 | class MaySolDay8 {
11 |
12 | func checkStraightLine(_ coordinates: [[Int]]) -> Bool {
13 | guard coordinates.count > 1 else { return false }
14 |
15 | if coordinates.count == 2 {
16 | return true
17 | }
18 |
19 | let vertical = (coordinates[1][0] - coordinates[0][0]) == 0
20 | let horizontal = (coordinates[1][1] - coordinates[0][1]) == 0
21 |
22 | let slope = (horizontal || vertical) ?
23 | 0 : (coordinates[1][0] - coordinates[0][0])/(coordinates[1][1] - coordinates[0][1])
24 | for idx in 2.. Bool {
12 | if num == 1 {
13 | return true
14 | }
15 |
16 | for number in 1...num/2 {
17 | let result = number * number
18 | if result >= num {
19 | return result == num
20 | }
21 | }
22 |
23 | return false
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay15.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay15.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/maximum-sum-circular-subarray/
10 | class MaySolDay15 {
11 | func maxSubarraySumCircular(_ A: [Int]) -> Int {
12 | guard A.count > 0 else { return 0 }
13 | if A.count == 1 {
14 | return A[0]
15 | }
16 |
17 | var output = Int.min
18 | var current = A[0]
19 | // Single interval
20 | for i in 1.. SinglyListNode? {
13 | guard head != nil else { return nil }
14 |
15 | var odd = head
16 | var even = head?.next
17 | let evenHead = even
18 |
19 | while even != nil, even?.next != nil {
20 | odd?.next = even?.next
21 | odd = odd?.next
22 |
23 | even?.next = odd?.next
24 | even = even?.next
25 | }
26 |
27 | odd?.next = evenHead
28 | return head
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay17.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay17.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/find-all-anagrams-in-a-string/
10 | class MaySolDay17 {
11 |
12 | func findAnagrams(_ s: String, _ p: String) -> [Int] {
13 | guard s.count >= p.count else { return [] }
14 |
15 | var output = [Int]()
16 | let arrP = Array(p), arrS = Array(s)
17 |
18 | var dictS = [Character : Int]()
19 | var dictP = dictS
20 |
21 | var idx = 0
22 | while idx < arrP.count {
23 | dictS[arrS[idx]] = dictS[arrS[idx]] == nil ? 1 : dictS[arrS[idx]]! + 1
24 | dictP[arrP[idx]] = dictP[arrP[idx]] == nil ? 1 : dictP[arrP[idx]]! + 1
25 | idx += 1
26 | }
27 |
28 | if dictS == dictP {
29 | output.append(0)
30 | }
31 |
32 | idx = 1
33 | while idx + arrP.count - 1 < arrS.count {
34 | dictS[arrS[idx - 1]]! -= 1
35 | if dictS[arrS[idx - 1]]! == 0 {
36 | dictS[arrS[idx - 1]] = nil
37 | }
38 |
39 | let temp = idx + arrP.count - 1
40 | dictS[arrS[temp]] = dictS[arrS[temp]] == nil ? 1 : dictS[arrS[temp]]! + 1
41 |
42 | if dictS == dictP {
43 | output.append(idx)
44 | }
45 |
46 | idx += 1
47 | }
48 |
49 | return output
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay18.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay18.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/permutation-in-string/
10 | class MaySolDay18 {
11 |
12 | func checkInclusion(_ s1: String, _ s2: String) -> Bool {
13 | var dict = [Character:Int]()
14 | for ch in s1 {
15 | dict[ch] = dict[ch] == nil ? 1 : dict[ch]! + 1
16 | }
17 |
18 | let arrS = Array(s2)
19 | var idx = 0
20 | while idx < arrS.count {
21 | let ch = arrS[idx]
22 | if dict[ch] != nil {
23 | var temp = dict
24 | var tempIdx = idx
25 | while tempIdx < arrS.count {
26 | if temp[arrS[tempIdx]] == nil {
27 | break
28 | } else {
29 | temp[arrS[tempIdx]]! -= 1
30 | if temp[arrS[tempIdx]]! == 0 {
31 | temp[arrS[tempIdx]] = nil
32 | }
33 | }
34 | tempIdx += 1
35 | }
36 |
37 | if temp.isEmpty {
38 | return true
39 | }
40 |
41 | }
42 | idx += 1
43 | }
44 |
45 | return false
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay19.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay19.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class MaySolDay19 {
12 |
13 | class StockSpanner {
14 | var stack = [(Int, Int)]()
15 |
16 | init() {
17 |
18 | }
19 |
20 | func next(_ price: Int) -> Int {
21 | var span = 1
22 | while !stack.isEmpty, price >= stack.last!.0 {
23 | span += stack.removeLast().1
24 | }
25 | stack.append((price, span))
26 | return span
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay20.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay20.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/kth-smallest-element-in-a-bst/
10 | class MaySolDay20 {
11 |
12 | func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
13 | guard let root = root else { return -1 }
14 | var arr = [Int]()
15 | traverse(root, &arr)
16 | arr.sort()
17 | return arr[k - 1]
18 | }
19 |
20 | private func traverse(_ root: TreeNode?, _ arr: inout [Int]) {
21 | guard let root = root else { return }
22 |
23 | arr.append(root.val)
24 |
25 | if let left = root.left {
26 | traverse(left, &arr)
27 | }
28 |
29 | if let right = root.right {
30 | traverse(right, &arr)
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay21.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay21.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/30/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/count-square-submatrices-with-all-ones/
10 | class MaySolDay21 {
11 | func countSquares(_ matrix: [[Int]]) -> Int {
12 | var output = 0
13 | var dp = matrix
14 | for x in 0.. 0, y > 0 {
20 | dp[x][y] = min(dp[x - 1][y], dp[x][y - 1], dp[x - 1][y - 1]) + 1
21 | output += dp[x][y] > 1 ? dp[x][y] - 1 : 0
22 | }
23 | }
24 | }
25 | }
26 | return output
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay22.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay22.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/31/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/sort-characters-by-frequency/
10 | class MaySolDay22 {
11 |
12 | func frequencySort(_ s: String) -> String {
13 | var freqDict = [Character:Int]()
14 | var map = [Int:[Character]]()
15 | var output = [Character]()
16 | for ch in s {
17 | freqDict[ch] = freqDict[ch] == nil ? 1 : freqDict[ch]! + 1
18 | }
19 |
20 | for key in freqDict.keys {
21 | if map[freqDict[key]!] != nil {
22 | map[freqDict[key]!]!.append(key)
23 | } else {
24 | map[freqDict[key]!] = [key]
25 | }
26 | }
27 |
28 | let sortedKeys = map.keys.sorted(by: >)
29 | for key in sortedKeys {
30 | for value in map[key]! {
31 | for _ in 0.. [[Int]] {
13 | guard !A.isEmpty, !B.isEmpty else {
14 | return []
15 | }
16 |
17 | var output = [[Int]]()
18 | var aIdx = 0
19 | var bIdx = 0
20 | var last = [Int]()
21 | while aIdx < A.count || bIdx < B.count {
22 | if last.isEmpty {
23 | guard aIdx < A.count, bIdx < B.count else { break }
24 |
25 | if aIdx < A.count, A[aIdx][0] < B[bIdx][0] {
26 | last = A[aIdx]
27 | aIdx += 1
28 | } else {
29 | last = B[bIdx]
30 | bIdx += 1
31 | }
32 | } else {
33 | while (aIdx < A.count && A[aIdx][0] <= last[1]) ||
34 | (bIdx < B.count && B[bIdx][0] <= last[1]) {
35 | if aIdx < A.count, A[aIdx][0] <= last[1] {
36 | output.append([max(last[0], A[aIdx][0]), min(last[1], A[aIdx][1])])
37 | last = [min(last[0], A[aIdx][0]), max(last[1], A[aIdx][1])]
38 | aIdx += 1
39 | }
40 |
41 | if bIdx < B.count, B[bIdx][0] <= last[1] {
42 | output.append([max(last[0], B[bIdx][0]), min(last[1], B[bIdx][1])])
43 | last = [min(last[0], B[bIdx][0]), max(last[1], B[bIdx][1])]
44 | bIdx += 1
45 | }
46 | }
47 | last = []
48 | }
49 | }
50 |
51 | return output
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay24.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay24.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/31/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/
10 | class MaySolDay24 {
11 |
12 | func bstFromPreorder(_ preorder: [Int]) -> TreeNode? {
13 | guard preorder.count > 0 else { return nil }
14 | return bstFromPreorder(preorder, 0, preorder.count - 1)
15 | }
16 |
17 | private func bstFromPreorder(_ preorder: [Int], _ start: Int, _ end: Int) -> TreeNode? {
18 | let root = TreeNode(preorder[start])
19 |
20 | if start + 1 <= end, preorder.count > 1 {
21 | var rightRootIdx = -1
22 | for idx in start+1...end {
23 | if preorder[idx] > preorder[start] {
24 | rightRootIdx = idx
25 | break
26 | }
27 | }
28 |
29 | if rightRootIdx == start + 1 {
30 | root.right = bstFromPreorder(preorder, rightRootIdx, end)
31 | } else if rightRootIdx == -1 {
32 | root.left = bstFromPreorder(preorder, start + 1, end)
33 | } else {
34 | root.right = bstFromPreorder(preorder, rightRootIdx, end)
35 | root.left = bstFromPreorder(preorder, start + 1, rightRootIdx - 1)
36 | }
37 | }
38 | return root
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay25.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay25.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/31/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/uncrossed-lines/
10 | class MaySolDay25 {
11 |
12 | func maxUncrossedLines(_ A: [Int], _ B: [Int]) -> Int {
13 | var dp = Array(repeating: Array(repeating: 0, count: B.count+1), count: A.count+1)
14 | for i in 1...A.count {
15 | for j in 1...B.count {
16 | dp[i][j] = (A[i-1] == B[j-1]) ? (1 + dp[i-1][j-1]) : max(dp[i-1][j], dp[i][j-1])
17 | }
18 | }
19 | return dp[A.count][B.count]
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay26.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay26.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/31/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/contiguous-array/
10 | class MaySolDay26 {
11 |
12 | func findMaxLength(_ nums: [Int]) -> Int {
13 | var dict = [0:-1]
14 |
15 | var maxCount = 0
16 | var count = 0
17 | for idx in 0.. Bool {
13 | graph = Array(repeating: [Int](), count: N+1)
14 | for dislike in dislikes {
15 | let d0 = dislike[0], d1 = dislike[1]
16 | graph[d0].append(d1)
17 | graph[d1].append(d0)
18 | }
19 | for node in 1...N {
20 | if color[node] == nil && !dfs(node, 0) { return false }
21 | }
22 | return true
23 | }
24 |
25 | private var graph = [[Int]]()
26 | private var color = [Int: Int]()
27 | private func dfs(_ node: Int, _ c: Int) -> Bool {
28 | if let v = color[node] { return v == c }
29 | color[node] = c
30 | for i in graph[node] {
31 | if !dfs(i, c ^ 1) { return false }
32 | }
33 | return true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay28.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay28.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 5/31/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/counting-bits/
10 | class MaySolDay28 {
11 |
12 | func countBits(_ num: Int) -> [Int] {
13 | var output = [Int]()
14 | for i in 0...num {
15 | output.append(helper(i))
16 | }
17 | return output
18 | }
19 |
20 | func helper(_ num: Int) -> Int {
21 | var count = 0
22 | var input = num
23 | while input != 0 {
24 | input = input & (input - 1)
25 | count += 1
26 | }
27 | return count
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek5/MaySolDay29.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay29.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 6/3/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/course-schedule/
10 | class MaySolDay29 {
11 | func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
12 | var preDict = [Int:[Int]]()
13 | for pre in prerequisites {
14 | if preDict[pre[0]] == nil {
15 | preDict[pre[0]] = [pre[1]]
16 | } else {
17 | preDict[pre[0]]!.append(pre[1])
18 | }
19 | }
20 |
21 | var okCourse = Set()
22 | for course in 1...numCourses {
23 | var taken = Set()
24 | if helper(course, preDict, &okCourse, &taken) {
25 | okCourse.insert(course)
26 | } else {
27 | return false
28 | }
29 | }
30 |
31 | return true
32 | }
33 |
34 | private func helper(_ current: Int, _ preDict: [Int:[Int]], _ okCourse: inout Set, _ taken: inout Set) -> Bool {
35 | if okCourse.contains(current) {
36 | return true
37 | }
38 | if taken.contains(current) {
39 | return false
40 | }
41 |
42 | taken.insert(current)
43 | if preDict[current] != nil {
44 | for pre in preDict[current]! {
45 | if helper(pre, preDict, &okCourse, &taken) {
46 | okCourse.insert(pre)
47 | } else {
48 | return false
49 | }
50 | }
51 | } else {
52 | return true
53 | }
54 | return true
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek5/MaySolDay30.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay30.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 6/4/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/k-closest-points-to-origin/
10 | class MaySolDay30 {
11 | func kClosest(_ points: [[Int]], _ K: Int) -> [[Int]] {
12 | let sorted = points.sorted { getDistance($0) < getDistance($1) }
13 | return Array(sorted[0.. Int {
17 | return point[0] * point[0] + point[1] * point[1]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/MayWeek5/MaySolDay31.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MaySolDay31.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 6/4/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | // LeetCode: https://leetcode.com/problems/edit-distance/
10 | class MaySolDay31 {
11 | func minDistance(_ word1: String, _ word2: String) -> Int {
12 | let row = word1.count + 1
13 | let column = word2.count + 1
14 | var dp = Array(repeating: Array(repeating: 0, count: column), count: row)
15 | let array1 = Array(word1)
16 | let array2 = Array(word2)
17 |
18 | for i in 0.. Bool {
46 | return lhs.val < rhs.val
47 | }
48 |
49 | public static func == (lhs: TreeNode, rhs: TreeNode) -> Bool {
50 | return lhs.val == rhs.val
51 | }
52 |
53 | }
54 |
55 | public class BinarySearchTree {
56 | private var root: TreeNode?
57 |
58 | // Init BinarySearchTree by its root node
59 | init(root: TreeNode?) {
60 | if !BinarySearchTree.isValidBinarySearchTree(root) {
61 | assertionFailure("This is not a valid binary search tree.")
62 | }
63 | self.root = root
64 | }
65 |
66 | public func isEqualToOtherTree(_ otherRoot: TreeNode?) -> Bool {
67 | return BinarySearchTree.preorderTraversal(self.root) == BinarySearchTree.preorderTraversal(otherRoot)
68 | }
69 | /**
70 | A binary search tree is a binary tree where for every node, any descendant of node.left
71 | has a value < node.val, and any descendant of node.right has a value > node.val.
72 |
73 | - Parameter root: The root of the binary search tree to be examinated.
74 |
75 | - Returns: A boolean indicates whether the binary tree is a binary search tree.
76 | */
77 | public static func isValidBinarySearchTree(_ root: TreeNode?) -> Bool {
78 | guard let root = root else {
79 | return false
80 | }
81 |
82 | if let left = root.left, let right = root.right {
83 | return left.val < root.val && isValidBinarySearchTree(left) &&
84 | right.val > root.val && isValidBinarySearchTree(right)
85 | } else if let left = root.left {
86 | return left.val < root.val && isValidBinarySearchTree(left)
87 | } else if let right = root.right {
88 | return right.val > root.val && isValidBinarySearchTree(right)
89 | }
90 |
91 | return true
92 | }
93 |
94 | public static func preorderTraversal(_ root: TreeNode?) -> [Int] {
95 | var traversal = [Int]()
96 | guard let root = root else {
97 | return traversal
98 | }
99 |
100 | traversal.append(root.val)
101 | if let left = root.left {
102 | traversal.append(contentsOf: preorderTraversal(left))
103 | }
104 |
105 | if let right = root.right {
106 | traversal.append(contentsOf: preorderTraversal(right))
107 | }
108 |
109 | return traversal
110 | }
111 | }
112 |
113 | // This is the BinaryMatrix's API.
114 | public class BinaryMatrix {
115 | var matrix = [[Int]]()
116 |
117 | init(matrix: [[Int]]) {
118 | guard matrix.count > 0 else {
119 | assertionFailure("Empty input.")
120 | return
121 | }
122 |
123 | let columnCount = matrix[0].count
124 | for idx in 0.. Int {
134 | guard x < self.matrix.count || y < self.matrix[0].count else {
135 | assertionFailure("Index out of bound.")
136 | return -1
137 | }
138 | return matrix[x][y]
139 | }
140 |
141 | public func dimensions() -> [Int] {
142 | return [self.matrix.count, self.matrix[0].count]
143 | }
144 | }
145 |
146 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/Shared/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/15/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | extension Array where Element == Int {
10 |
11 | public func convertToLinkedList() -> SinglyListNode? {
12 | guard self.count > 0 else {
13 | return nil
14 | }
15 |
16 | let head = SinglyListNode(self[0])
17 | var idx = 1
18 | var node: SinglyListNode? = head
19 |
20 | while idx < self.count {
21 | node?.next = SinglyListNode(self[idx])
22 | node = node?.next
23 | idx += 1
24 | }
25 | return head
26 | }
27 | }
28 |
29 | extension Array where Element == Int? {
30 |
31 | public func convertToBinaryTree() -> TreeNode? {
32 | guard self.count > 0 else {
33 | return nil
34 | }
35 |
36 | let root = TreeNode(self[0]!)
37 | constructTreeLevelOrder(0, root, self)
38 | return root
39 | }
40 |
41 | private func constructTreeLevelOrder(_ index: Int, _ root: TreeNode?, _ arr: [Int?]) {
42 | guard let root = root else { return }
43 |
44 | if index < arr.count {
45 | if 2*index+1 < arr.count, let val = arr[2*index+1] {
46 | root.left = TreeNode(val)
47 | constructTreeLevelOrder(2*index+1, root.left, arr)
48 | }
49 | if 2*index+2 < arr.count, let val = arr[2*index+2] {
50 | root.right = TreeNode(val)
51 | constructTreeLevelOrder(2*index+2, root.right, arr)
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/LeetCodeChallenge/LeetCodeChallenge/main.swift:
--------------------------------------------------------------------------------
1 | //
2 | // main.swift
3 | // LeetCodeChallenge
4 | //
5 | // Created by Michael Ho on 4/13/20.
6 | // Copyright © 2020 Michael Ho. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | This place is used as a playground! Feel free to debug here.
13 |
14 | Command + U to run all tests.
15 | */
16 | print("Hello My LeetCode Challenge!")
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Leetcode 30-Day Challenge April and May Edition
2 |
3 | [](https://developer.apple.com/swift/) [](https://github.com/twho/LeetCode-Swift/blob/master/LICENSE)
4 |
5 | ## Summary
6 | - This project aims at solving [LeetCode 30-Day Challenge April Edition](https://leetcode.com/explore/featured/card/30-day-leetcoding-challenge/) and [May LeetCoding Challenge](https://leetcode.com/explore/featured/card/may-leetcoding-challenge/) problems.
7 | - We provide straightforward solutions. All solutions and tests are written in [Swift](https://developer.apple.com/swift/).
8 | - There are **30** programming problems and solutions for April challenge.
9 | - An additional set of **30** code problems and solutions will be uploaded by the end of [May LeetCoding Challenge](https://leetcode.com/explore/featured/card/may-leetcoding-challenge/).
10 |
11 | ## Articles for April Edition
12 | - [iOS Interview Prep Guide: 30-Day Code Challenge in Swift — Week 1/5](https://medium.com/@twho/ios-interview-prep-guide-30-day-code-challenge-in-swift-week-1-5-7198c6a1477a)
13 | - [iOS Interview Prep Guide: 30-Day Code Challenge in Swift — Week 2/5](https://medium.com/@twho/ios-interview-prep-guide-30-day-code-challenge-in-swift-week-2-5-f8d14df99179)
14 | - [iOS Interview Prep Guide: 30-Day Code Challenge in Swift — Week 3/5](https://medium.com/@twho/ios-interview-prep-guide-30-day-code-challenge-in-swift-week-3-5-463f9bb8c4f5)
15 | - [iOS Interview Prep Guide: 30-Day Code Challenge in Swift — Week 4/5](https://medium.com/@twho/ios-interview-prep-guide-30-day-code-challenge-in-swift-week-4-5-647f6050e869)
16 | - [iOS Interview Prep Guide: 30-Day Code Challenge in Swift — Week 5/5](https://medium.com/swlh/ios-interview-prep-guide-30-day-code-challenge-in-swift-week-5-5-d093e2cd4217)
17 |
18 | ## Articles for May Edition
19 | *Updating in progress*
20 | - [Top 15 Swift Code Interview Questions from May Code Challenge — Part 1/3](https://medium.com/swlh/top-15-swift-code-interview-questions-from-may-code-challenge-part-1-3-65c3dc11851b)
21 |
22 | ## Difficulty Legends
23 | | Difficulty | Easy | Medium | Hard |
24 | |:--: | :--: | :--: | :--: |
25 | | Icon | 📗 | 📙 | 📕 |
26 |
27 | ## April Challenge
28 | ### April 1st - April 30th
29 | | Day | Diffculty | Problem | Solution |
30 | |:--:| :--: | :-- | -- |
31 | | 1 |📗|[Single Number](https://leetcode.com/problems/single-number/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay1.swift)|
32 | | 2 |📗| [Happy Number](https://leetcode.com/problems/happy-number/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay2.swift)|
33 | | 3 |📗| [Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay3.swift)|
34 | | 4 |📗| [Move Zeroes](https://leetcode.com/problems/move-zeroes/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay4.swift)|
35 | | 5 |📗| [Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay5.swift)|
36 | | 6 |📙| [Group Anagrams](https://leetcode.com/problems/group-anagrams/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay6.swift)|
37 | | 7 |📗| [Counting Elements](https://leetcode.com/problems/counting-elements/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek1/AprilSolDay7.swift)|
38 | | 8 |📗| [Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay8.swift)|
39 | | 9 |📗| [Backspace String Compare](https://leetcode.com/problems/backspace-string-compare/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay9.swift)|
40 | | 10 |📗| [Min Stack](https://leetcode.com/problems/min-stack/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay10.swift)|
41 | | 11 |📗| [Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay11.swift)|
42 | | 12 |📗| [Last Stone Weight](https://leetcode.com/problems/last-stone-weight/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay12.swift)|
43 | | 13 |📙| [Contiguous Array](https://leetcode.com/problems/contiguous-array/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay13.swift)|
44 | | 14 |📗| [Perform String Shifts](https://leetcode.com/problems/perform-string-shifts/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek2/AprilSolDay14.swift)|
45 | | 15 |📙| [Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay15.swift)|
46 | | 16 |📙| [Valid Parenthesis String](https://leetcode.com/problems/valid-parenthesis-string/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay16.swift)|
47 | | 17 |📙| [Number of Islands](https://leetcode.com/problems/number-of-islands/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay17.swift)|
48 | | 18 |📙| [Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay18.swift)|
49 | | 19 |📙| [Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay19.swift)|
50 | | 20 |📙| [Construct Binary Search Tree from Preorder Traversal](https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay20.swift)|
51 | | 21 |📙| [Leftmost Column with at Least a One](https://leetcode.com/problems/leftmost-column-with-at-least-a-one/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek3/AprilSolDay21.swift)|
52 | | 22 |📙| [Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay22.swift)|
53 | | 23 |📙| [Bitwise AND of Numbers Range](https://leetcode.com/problems/bitwise-and-of-numbers-range/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay23.swift)|
54 | | 24 |📙| [LRU Cache](https://leetcode.com/problems/lru-cache/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay24.swift)|
55 | | 25 |📙| [Jump Game](https://leetcode.com/problems/jump-game/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay25.swift)|
56 | | 26 |📙| [Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay26.swift)|
57 | | 27 |📙| [Maximal Square](https://leetcode.com/problems/maximal-square/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay27.swift)|
58 | | 28 |📙| [First Unique Number](https://leetcode.com/problems/first-unique-number/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek4/AprilSolDay28.swift)|
59 | | 29 |📕| [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek5/AprilSolDay29.swift)|
60 | | 30 |📙| [A String Is a Root-to-Leaf Path in a Binary Tree](https://leetcode.com/problems/check-if-a-string-is-a-valid-sequence-from-root-to-leaves-path-in-a-binary-tree/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/AprilWeek5/AprilSolDay30.swift)|
61 |
62 | ## May Challenge
63 | ### May 1st - May 31st
64 | | Day | Diffculty | Problem | Solution |
65 | |:--:| :--: | :-- | -- |
66 | | 1 |📗|[First Bad Version](https://leetcode.com/problems/first-bad-version/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay1.swift)|
67 | | 2 |📗|[Jewels and Stones](https://leetcode.com/problems/jewels-and-stones/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay2.swift)|
68 | | 3 |📗|[Ransom Note](https://leetcode.com/problems/ransom-note/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay4.swift)|
69 | | 4 |📗|[Number Complement](https://leetcode.com/problems/number-complement/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay4.swift)|
70 | | 5 |📗|[First Unique Character in a String](https://leetcode.com/problems/first-unique-character-in-a-string/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay5.swift)|
71 | | 6 |📗|[Majority Element](https://leetcode.com/problems/majority-element/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay6.swift)|
72 | | 7 |📗|[Cousins in Binary Tree](https://leetcode.com/problems/cousins-in-binary-tree/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek1/MaySolDay7.swift)|
73 | | 8 |📗|[Check If It Is a Straight Line](https://leetcode.com/problems/check-if-it-is-a-straight-line/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay8.swift)|
74 | | 9 |📗|[Valid Perfect Square](https://leetcode.com/problems/valid-perfect-square/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay9.swift)|
75 | | 10 |📗|[Find the Town Judge](https://leetcode.com/problems/find-the-town-judge/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay10.swift)|
76 | | 11 |📗|[Flood Fill](https://leetcode.com/problems/flood-fill/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay11.swift)|
77 | | 12 |📙|[Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay12.swift)|
78 | | 13 |📙|[Remove K Digits](https://leetcode.com/problems/remove-k-digits/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay13.swift)|
79 | | 14 |📙|[Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek2/MaySolDay14.swift)|
80 | | 15 |📙|[Maximum Sum Circular Subarray](https://leetcode.com/problems/maximum-sum-circular-subarray/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay15.swift)|
81 | | 16 |📙|[Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay16.swift)|
82 | | 17 |📙|[Find All Anagrams in a String](https://leetcode.com/problems/find-all-anagrams-in-a-string/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay17.swift)|
83 | | 18 |📙|[Permutation in String](https://leetcode.com/problems/permutation-in-string/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay18.swift)|
84 | | 19 |📙|[Online Stock Span](https://leetcode.com/problems/online-stock-span/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay19.swift)|
85 | | 20 |📙|[Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay20.swift)|
86 | | 21 |📙|[Count Square Submatrices with All Ones](https://leetcode.com/problems/count-square-submatrices-with-all-ones/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek3/MaySolDay21.swift)|
87 | | 22 |📙|[Sort Characters By Frequency](https://leetcode.com/problems/sort-characters-by-frequency/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay22.swift)|
88 | | 23 |📙|[Interval List Intersections](https://leetcode.com/problems/interval-list-intersections/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay23.swift)|
89 | | 24 |📙|[Construct Binary Search Tree from Preorder Traversal](https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay24.swift)|
90 | | 25 |📙|[Uncrossed Lines](https://leetcode.com/problems/uncrossed-lines/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay25.swift)|
91 | | 26 |📙|[Contiguous Array](https://leetcode.com/problems/contiguous-array/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay26.swift)|
92 | | 27 |📙|[Possible Bipartition](https://leetcode.com/problems/possible-bipartition/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay27.swift)|
93 | | 28 |📙|[Counting Bits](https://leetcode.com/problems/counting-bits/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek4/MaySolDay28.swift)|
94 | | 29 |📙|[Course Schedule](https://leetcode.com/problems/course-schedule/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek5/MaySolDay29.swift)|
95 | | 30 |📙|[K Closest Points to Origin](https://leetcode.com/problems/k-closest-points-to-origin/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek5/MaySolDay30.swift)|
96 | | 31 |📕|[Edit Distance](https://leetcode.com/problems/edit-distance/) | [Solution](https://github.com/twho/leetcode-30-day-challenge-swift/blob/master/LeetCodeChallenge/LeetCodeChallenge/MayWeek5/MaySolDay31.swift)|
97 |
--------------------------------------------------------------------------------