LeetCode ์ Top Interview Questions ์ ๊ธฐ์ฌ๋์ด ์๋ Easy ๋ฌธ์ ๋ค์ ํ์ด๋ณด์.
Ex) LeetCode #9: Palindrome
๊ณ ๋ฏผ ๊ณผ ํด๊ฒฐ
- ์ด๋ป๊ฒ x ์ integer ๊ฐ์ ๋ค์ง์๊น?1.0: x ๊ฐ์ 10 ์ผ๋ก ๋๋ ๋๋จธ์ง ๊ฐ, ์ฒซ์งธ (1์) ์๋ฆฌ ๊ฐ์ ์ ์ฅํ๋ค.
2.0: 10 ์ผ๋ก x ๊ฐ์ ๋๋๋ค
3.0: x ๊ฐ 0 ์ด ๋ ๋๊น์ง 1,2 ๋ฒ ํ๋ก์ธ์ค๋ฅผ ๋ฐ๋ณตํ๋ค.
-
x ๊ฐ ์์์ผ๋๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ๊น?
- ์์์ผ๊ฒฝ์ฐ ์ด๋์กฐํฉ์ด ์ค๋ Palindrome(ํ๋ฌธ) ์กฐ๊ฑด์ด ์ฑ๋ฆฝํ์ง ์์์ผ๋ก false ๋ฅผ ๋ฐํํ๊ฒ ์ฒ๋ฆฌ.
-
String ์ผ๋ก ๋ณํ์ ํ์ง ์๊ณ ์ด๋ป๊ฒ [Int] ์ ์๋ ๊ฐ๋ค์ ํ๋์ integer ๊ฐ์ผ๋ก ๋ง๋ค์ ์์๊น?
-
map ์ ์ฌ์ฉํด์ ํด๊ฒฐ
ex) digit = [1,2,1]
digit.reduce(0,{$0*10 + $1})
โ 0 * 10 + 1 = 1
โ 1 * 10 + 2 = 12
โ 12*10 + 1 = 121
-
1.0 Remove Duplicates from Sorted Array
-
์ด๋ฌธ์ ๋ 2๊ฐ์ง์ ์ ํ์ผ๋ก ์ ๊ทผํ๋ค.
-
1.0 ์ค๋ณต๋ ์์๋ฅผ ์ญ์ ํ๊ณ ๊ทธ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ฆฌํดํด์ค๋ค. (๋ฌธ์ ๊ฐ ์ํ๋ ๋ฐฉ๋ฒ์ด ์๋)
Set ์ ์ฌ์ฉํด์ ๋ฐฐ์ด์ ์ค๋ณต๋ ์์๋ฅผ ์์ค๋ค ๋ค์ increment ์์๋ก sort ํด์ค๋ค.
func removeDeplicates(_ nums: inout [Int]) -> Int {
nums = Array(Set(nums).sort({$0 < $1}))
return nums.count
}
- 2.0 ํ์ง๋ง ๋ฌธ์ ์ง๋ฌธ์์ ๋ค์๊ณผ ๊ฐ์ด ๋ช
์ํ๋ฏ์ด
"Since it is impossible to change the length of the array in some languages"
, ์ด๋ค ์ธ์ด์์ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ฐ๊ฟ์์๋ค. ๋ฐ๋ผ์ "In-place" ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ผ๊ณ ํ๋ค.
๊ณ ๋ฏผ
: ์ด๋ป๊ฒ ์ค๋ณต๋์์๋ฅผ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ์ ์งํ๋ฉด์ ๊ฑธ๋ฌ๋ผ์์์๊น?
์ ๊ทผ ๋ฐฉ์: ๋ฐฐ์ด์ ์ํํ๋ฉด์ ๋ค์ ์์๊ฐ๊ณผ ๊ฐ์ด ๊ฐ๋ค๋ฉด ๋ค์์์์ ๊ฐ์์์๊ฐ์ range ์ธ ๊ฐ์ผ๋ก ์ค์ ํด์ฃผ๊ณ ๋ง์ง๋ง์ filter ํด์ค๋ค.
๊ฒฐ๊ณผ: ์ฐ์ํด์ 2๊ฐ ์ด์์ ์์๊ฐ ๊ฐ์ ๊ฐ์ด๋ฉด ์ค๋ณต๋๊ฐ์ ๋ฐ๊พธ์ด ์ค์ ์์ -> ex) [1,1,1] -> [1,101,1]
์ ๊ทผ๋ฐฉ์
pointer
๋ผ๋ ๋ณ์๋ก ์์๋๋ก ์ ๋ ฌ๋์ด์๋ ์์๋ค์ ๋ง์ง๋ง ์ธ๋ฑ์ค๋ฅผ ๊ฐ๋ฅดํจ๋ค. -> ์ด๊ธฐ๊ฐ์ 1๋ก ์ค์ ํด๋์ด 0๋ฒ์งธ ์์์ ๋น๊ต๊ฐ๋ฅํ๊ฒ ์ค์ .- ๋ฐฐ์ด์ ์ํํ๋ฉด์ ์ค๋ณต์ผ๋ก ๋์ด๋์ด ์๋ ๊ฐ๊ณผ ๋ค๋ฅธ๊ฐ์ด ๋์ฌ๊ฒฝ์ฐ ๋ฐฐ์ด์
pointer
์ธ๋ฑ์ค์ ๋ฐ๋ ๊ฐ์ ๋์ ํด์ค๋ค.- ๊ฒฐ๊ณผ์ ์ผ๋ก ์ค๋ณต๋ ์์์ผ๋๋ pass, ๋ค๋ฅธ์์์ผ๋๋ pointer ๋ฅผ ์ฌ์ฉํด ๋ฐฐ์ด์ ์๋ถ๋ถ๋ถํฐ ์์๋๋ก ์ฑ์์ค๋ค.
func removeDeplicates(_ nums: inout [Int]) -> Int {
var pointer = 1
for i in 1..<nums.count {
if nums[i] != nums[i-1] {
nums[pointer] = nums[i]
pointer += 1
}
}
return pointer
}
2.0 Best Time to Buy and Sell Stock II
๊ณ ๋ฏผ
: Brute Force ๋ฐฉ๋ฒ ๋ง๊ณ ์ด๋ป๊ฒ ๋ฌธ์ ์ ์ ๊ทผํ ์ ์์๊น?
๊ทผ๊ฑฐ
: Stock ์ ์ฐ ๋ ๋ถํฐ ํ์์ profit ์ ๋ผ์ ์๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ณ์ฐ ํด์ผํ๊ธฐ ๋๋ฌธ์ time complexity ๊ฐ On^n ์ด ๋๋ค.
์ ๊ทผ๋ฐฉ์1
: ๋ฐฐ์ด์ ์ํํ๋ฉด์ ๊ฐ ๋ ์ง๋ง๋ค ์ต๋์ profit ์ ๋ํด์ค๋ค.
๊ฒฐ๊ณผ
: ํ ๋ ์ง์ ์ต๋ profit ์ ์ฃผ๋ selling ๋ ์ง๋ง ๊ตฌํ๋ฉด ๋ค๋ฅธ ๋ ์ง์ ํ์์ ์๊ธฐ๋ profit ์ ์กฐํฉ์ ๊ตฌํ ์ ์๊ฒ ๋๋ค. ๋ฐ์ ๊ทธ๋ฆผ์ ๋ณด๋ฉดvalley(i)
์peak(j)
๊ฐ๋ง ๊ณ์ฐํด์ค๊ฒ๊ณผ ๊ฐ๋ค.
์ ๊ทผ๋ฐฉ์2
: Net Profit ๊ตฌํ๊ธฐ. ์ฃผ์ด์ง ๋ฐฐ์ด์ stock price ๊ฐ๋ค์ ๊ฐ์ง๊ณ ๋์ฌ์ ์๋ profit ์ ํฉ์ ๊ตฌํ๋ ๋ฐฉ์์ด๋ค.
๊ฒฐ๊ณผ
: ์ฑ๊ณต.
class Solution {
func maxProfit(_ prices: [Int]) -> Int {
var profit = 0
for i in 1..<prices.count {
if price[i] > price[i-1] {
profit += price[i] - price[i-1]
}
}
return profit
}
}
Time Complexity = O(n)
Space Complexity = O(1)
3.0 Rotate Array
๊ณ ๋ฏผ
: ์ค๋ฅธ์ชฝ์ผ๋ก ์์๋ฅผ ์ฎ๊ธธ๋ ์ด๋ป๊ฒ ๋ค์ ๊ฐ์ ์ ์ฅํด์ ๊ทธ ๋ค์ ์ธ๋ฑ์ค์ ๋์
ํด์ค์ ์์๊น?
์ ๊ทผ ๋ฐฉ์: Extra Memory ๋ฅผ ์ฌ์ฉํด์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ
-
1.0 k ๊ฐ์ range ๋ 0 <= k <= 10^5 ์ด๊ธฐ ๋๋ฌธ์ ์ ์ฒด ๋ฐฐ์ด์ ํฌ๊ธฐ์ ๋๋์ด ๋จ์ด์ง ๊ฐ์ ๊ตฌํ๋ค. (์ด ๋๋จธ์ง ๊ฐ์ ์ค๋ฅธ์ชฝ์ผ๋ก shift ๋์ด์ง๋ ํ์์ด๋ค)
-
2.0 ๊ธฐ์กด๋ฐฐ์ด์ N ๋งํผ shift ๋๋ฉด ์ด๋ค ํจํด์ ๊ฐ๋์ง ํ์ธํด๋ณธ๋ค. ex) Given : [1,2,3,4,5,6,7] , shift right by 3 -> [5,6,7,1,2,3,4], ์์ ๋ฐฐ์ด์ ํจํด์ ์ดํด๋ณด์์๋ ๋ฐฐ์ด์ [5,6,7] ๊ณผ [1,2,3,4] ๋ก ๋๋์ ์๋ค.
-
4.0 Nums ์ ๊ฐ์ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง ์์๋ฐฐ์ด
temp
๋ฅผ ๋ง๋ค๊ณ [5,6,7], [1,2,3,4] ๋ฅผ ์ฐจ๋ก๋๋ก ๋ฃ์ด์ค์ ์๋ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐํด๋ณธ๋ค. -> ์ค๋ฅธ์ชฝ์ผ๋ก 3๋ฒ shift ํ๋ผ๋ k ๊ฐ์ ์ฌ์ฉํด ๊ธฐ์กด nums ๋ฐฐ์ด์์ [5,6,7] ์ ๋นผ๋ด์ด temps ์ ๋ฃ์ด์ค๋ค. -
5.0 ๋๋จธ์ง [1,2,3,4] ์ ๊ฐ์ temp ์ ๋ฃ์ด์ค๋ค nums ๋ฐฐ์ด์ ์ ๋ฐ์ดํธ ์์ผ์ค๋ค.
๊ฒฐ๊ณผ:
func rotateArray(_ nums: inout [Int], _ k: Int) {
//Shift ๋ ๊ฐ์ ๊ณ์ฐ
var offSet = k % nums.count
//nums ์ ํฌ๊ธฐ๋งํผ temp ๋ฐฐ์ด์์ฑ
var temp = Array(repeating: 0, count: nums.count)
//Temp ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ฅผ tracking ํด์ค ๊ฐ
var index = 0
//nums ๋์ ๊ธฐ์ค์ผ๋ก offSet ๊ฐ๋งํผ temp ์ ๋ฃ์ด์ค๋ค.
for i in (nums.count - offset)..<nums.count {
temp[index] = nums[i]
index += 1
}
//nums ์ ์์์ ๊ธฐ์ค์ผ๋ก offSet ๊ฐ๋งํผ temp ์ ๋ฃ์ด์ค๋ค.
for j in 0..<(nums.count-offSet) {
temp[index] = nums[j]
index += 1
}
//nums ์
๋ฐ์ดํธ
for k in 0..<nums.count {
nums[k] = temp[k]
}
}
//๋ฒ์ธ LeftShift ์ผ ๊ฒฝ์ฐ
//Given [1,2,3,4,5,6,7], leftShift by 2 -> [3,4,5,6,7,1,2]
//๋ฐฐ์ด์ [3,4,5,6,7] ๊ณผ [1,2] ๋ก ๋๋์ ์๋ค.
//temp ๋ฅผ ์ฌ์ฉํ์ฌ [3,4,5,6,7], [1,2] ๋ฅผ ์์๋๋ก ๋์
ํ ์ ์๊ฒ ๋ก์ง์ ๊ตฌํํ๋ค.
func leftRotateArray(_ nums: inout [Int], _ k: Int) {
var offSet = k % nums.count
var temp = Array(reapting:0, count: nums.count)
var index = 0
for i in offSet..<nums.count {
temp[index] = nums[i]
index += 1
}
for j in 0..<offSet {
temp[index] = nums[j]
index += 1
}
for k in 0..<nums.count {
nums[k] = temp[k]
}
}
Left Shift ์ Right Shift ์ ๊ธฐ์ค์ ์ ์์์ ์ผ๋ก ํ ๊ฑด์ง, ๋ง์ง๋ง ์์ ๋ก ํ ๊ฑด์ง๋ก ๊ตฌ๋ถํ ์ ์๋ค.
Time Complexity = O(n)
Space Complexity = O(n)
์ ๊ทผ ๋ฐฉ์: Element ๋ฅผ ํ๋์ฉ Shift ํ๋ ๋ฐฉ๋ฒ
- k ๊ฐ์ range ๋ 0 <= k <= 10^5 ์ด๊ธฐ ๋๋ฌธ์ ์ ์ฒด ๋ฐฐ์ด์ ํฌ๊ธฐ์ ๋๋์ด ๋จ์ด์ง ๊ฐ์ ๊ตฌํ๋ค. (์ด ๋๋จธ์ง ๊ฐ์ ์ค๋ฅธ์ชฝ์ผ๋ก shift ๋์ด์ง๋ ํ์์ด๋ค)
- Left Shift ์ธ๊ฒฝ์ฐ ํ์ฌ ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์์๋ฅผ ์ ์ฅํด๋์๋ค๊ฐ ์์๋ฅผ ํ๋์ฉ ์ผ์ชฝ์ผ๋ก ์ฎ๊ธดํ์ ๋ง์ง๋ง ์์์ ์ ์ฅํ ์ฒซ๋ฒ์งธ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด๋๋ค. ์ด๊ฒ์ k ๋ฒ ๋ฐ๋ณตํ๋ฉด๋๋๋ฐ ๋ฌธ์ ๋ Right Shift ๋ผ๋๊ฒ์ด๋ค.
i + 1
์์๋ฅผi
๋ฒ์งธ ์ธ๋ฑ์ค์ ๋ฃ๋๊ฑด ๊ฐ๋ฅํ์ง๋ง ๊ทธ ๋ฐ๋๋ ๋ถ๊ฐ๋ฅํ๋ค. (i + 1 ์ i ๋ฒ์งธ ์์๊ฐ ์ค๋ณตํด์ ํ ๋น๋จ)- ๋ฐ๋ผ์ nums ์
reversed()
์์ผ์ ๋ฌธ์ ๋ฅผ ํ์๋ค.
๊ฒฐ๊ณผ:
func rotate(_ nums: inout [Int], _ k: Int) {
var offSet = k % nums.count
//Nums ๋ฐฐ์ด์ ๋ค์ง์ด ์ค๋ค.
nums = nums.reversed()
while offSet > 0 {
let temp = nums.first!
for i in 0..<nums.count {
nums[i] = nums[i+1]
nums[nums.count-1] = temp
offSet -= 1
}
{
//Nums ๋ฐฐ์ด์ ์์ ์์๋ณต๊ตฌ
nums = nums.reversed()
}
time Complexity = On*k
space Complexity = O(1)
์ ๊ทผ ๋ฐฉ์: Juggling Alogrithm ์ ์ฌ์ฉ.
- ์๋2 ์ outer loop (k ๋ฒ ์คํ๋๋ loop) ๊ณผ inner loop (๊ฐ ์์๋ง๋ค shift ํ๊ธฐ์ํด ์คํด๋๋ loop) ๋๋ฌธ์
On*k
์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ฒ ๋๋ค. - Juggling Alogrithm ์ ๋ฐฐ์ด์ ๊ธธ์ด n, shift ๋๋ ํ์ k ์ GCD (์ต๋๊ณต์ฝ์) ๋ฅผ ๊ตฌํ์ฌ outer loop ์ ๋ง๋ ๋ค.
- Inner loop ์๋ k ์ ๊ฐ๋งํผ ๋จ์ด์ง ์ธ๋ฑ์ค์ ํ ๋น๋ ์๋ง์ ๋ฐฐ์ด์ ์์์ ํ ๋น์ํจ๋ค.
๊ฒฐ๊ณผ
func gcd(_ a: Int, _ b: Int) -> Int {
if b == 0 {return a}
else{
return gcd(b,a%b)
}
}
func rotateArray(_ nums: inout [Int], _ k: Int) {
let offSet = k % nums.count
for i in 0..<gcd(nums.count, offSet) {
let temp = nums[i]
//j = index of array that is to be replaced
var j = i
while true {
//d = pointing the next element to be shifted
//nums.count - offSet is used for right shift,
//(j-offSet) % offSet can be used for left shift
let d = (j+(nums.count-offSet)) % nums.count
if d == j {break}
nums[j] = nums[d]
j = d
}
nums[j] = temp
}
}
ex1) k ๊ฐ์ด ๋ฐฐ์ด๊ธธ์ด์ ์ฝ์ ์ผ๊ฒฝ์ฐ
nums = [1,2,3,4,5,6], k = 2
gcd = 2 (number of outer loop iteration)
@1st pass
temp = 1
j | d | nums |
---|---|---|
0 | 4 | [5,2,3,4,5,6] |
4 | 2 | [5,2,3,4,3,6] |
2 | 0 | [5,2,1,4,3,6] |
@2nd pass
temp = 2
j | d | nums |
---|---|---|
1 | 5 | [5,6,1,4,3,6] |
5 | 3 | [5,6,1,4,3,4] |
3 | 1 | [5,6,1,2,3,4] |
Time Complexity = O(N)
Space Complexity = O(1)
4.0 Contains Duplicate
๊ณ ๋ฏผ
= ์๊ฐ ๋ณต์ก๋์ ๊ณต๊ฐ๋ณต์ก๋๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํ์ด ๋ด์ผ๊ฒ ๋ค.
์ ๊ทผ ๋ฐฉ์
-
2์ค for loop = ์๊ฐ๋ณต์ก๋ On^2 (๋๋ฌด ๊น)
-
๋์ ๋๋ฆฌ = ์๊ฐ๋ณต์ก๋ O(N), ์ด์ง๋ง Memory ๋ฅผ ๋ง์ด ์ก์๋จน์
-
Set = ์๊ฐ๋ณต์ก๋ O(N), ๋์ ๋๋ฆฌ ๋ณด๋ค ์ ๊ฒ memory ์ฌ์ฉ.
๊ฒฐ๊ณผ
var set = Set<Int>()
for num in nums {
if set.contains(num) {return true}
set.insert(num)
}
return false
5.0 singleNumber
์ ๊ทผ๋ฐฉ์
1.0 Using Dictionary
func singleNumber(_ nums:[Int]) -> Int {
var counter: [Int: Int] = [:]
for num in nums {
if let count = counter[num] {
counter.updateValue(count + 1, forKey: num)
}else {
counter.updateValue(1, forKey: num)
}
}
if let res = counter.first(where: {$0.value == 1}) {
return res.key
}
return 0
}
2.0 Using Set
func singleNumber(_ nums:[Int]) -> Int {
var set = Set<Int>()
for num in nums {
if set.contains(num) {
set.remove(num)
}else {
set.insert(num)
}
}
return set.first!
}
6.0 Intersection of Two Arrays II
์ ๊ทผ๋ฐฉ์ : Brute Force
- ๋๋ฐฐ์ด์ ์์๋ฅผ ์์๋๋ก ํ๋์ฉ ๋น๊ตํ์ฌ ๊ฐ์ ๊ฐ์
res
๋ฐฐ์ด์ ๋ํด์ฃผ๋ ๋ฐฉ์์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐ ํ๋ค.
๊ฒฐ๊ณผ
func intersect(_ nums1: [Int], _ nums2: [Int]) -> [Int] {
var res: [Int] = []
var outter = nums1.count >= nums2.count ? nums2: nums1
var inner = nums1.count >= nums2.count ? nums1: nums2
var m = outter.count
while m > 0 {
let lastElement = outter.last!
if let matchedIndex = inner.firstIndex(where: {$0 == lastElement}) {
res.append(lastElement)
inner.remove(at: matchedIndex)
}
outter.removeLast()
m -= 1
}
return res
}
Time Complexity = O(N*M)
Space Complexity = O(1) (idealy)
์ ๊ทผ๋ฐฉ์ : Binary Search
- ์๋ 1 ์์ ๊ฐ์ ์์๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ผ๋ก
firstIndex
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋๋ฐ, binary search ๋ฅผ ์ฌ์ฉํด์O(nlogn + mlogn)
Time Complexity ๋ฅผ ๊ฐ์ ํด๋ณด์.
๊ฒฐ๊ณผ
func binarySearch(_ arr: [Int], _ value: Int, _ low: Int, _ high: Int) -> Int {
if low > high {return -1}
let mid = (low + high) / 2
if arr[mid] == value {
return mid
}
else if arr[mid] > value {
return binarySearch(arr, value, low, mid - 1)
}
else if arr[mid] < value {
return binarySearch(arr, value, mid + 1, high)
}
return -1
}
func intersect(_ nums1: [Int], _ nums2: [Int]) -> [Int] {
var res: [Int] = []
var outter = nums1.count >= nums2.count ? nums2: nums1
var inner = nums1.count >= nums2.count ? nums1: nums2
var m = outter.count
while m > 0 {
let lastElement = outter.last!
inner = inner.sorted(by: <)
let matchedIndex = binarySearch(inner, lastElement, 0, inner.count - 1)
if matchedIndex >= 0 {
res.append(lastElement)
inner.remove(at: matchedIndex)
}
outter.removeLast()
m -= 1
}
return res
}
Time Complexity = O(nlogn + mlogn)
Space Complexity = O(1)
7.0 Plus One
๊ณ ๋ฏผ
= String ์ Integer ๋ก ๋ณํ ํด์ ๊ณ์ฐํ๋ฉด, Integer ์ limit์ ๋์์๊ฐ ์๋ค. ๋ฐ๋ผ์ ๋ฐฐ์ด ์์ฒด๋ก ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ ๊ณ ๋ฏผํด๋ดค๋ค.
์ ๊ทผ๋ฐฉ์
-
์ฃผ์ด์ง digits ๋ฐฐ์ด์ ๋๋ถํฐ 1 ์ ๋ํ ๊ฐ์ด 9 ๋ฅผ ๋์ผ๋ฉด carry ๋ฅผ 1, ์๋๋ฉด carry ๋ฅผ 0 ์ผ๋ก ์ค์ ํด์ฃผ์ด ๋ค์ ์์๋ฅผ ๊ณ์ฐํ๋ ๋ฐฉ์์ผ๋ก ์ ๊ทผํ๋ค.
-
๋ง์ง๋ง ์์๋ถํฐ ์์ํด์ ์ฒซ๋ฒ์งธ ์์์ ๋๋ฌํ์๋์ ๊ฐ๊ณผ carry ๋ก ๋์ด์จ ๊ฐ์ ๋ํด 10 ์ด ๋๋ค๋ฉด ๊ฒฐ๊ณผ๊ฐ์ ๋ด์
res
๋ฐฐ์ด์ [0,1] ์ ํ ๋นํ๋ค. -
๋์ผ๋ก
res
๋ฐฐ์ด์ reverse ํด์ ๋ฐํ.
๊ฒฐ๊ณผ
func plusOne(_ digits: [Int]) -> [Int] {
var res: [Int] = []
var carry = 1
var index = digits.count - 1
while index > -1 {
let sum = digits[index] + carry
if index == 0 && sum > 9 {
res += [0,1]
}else if sum > 9 {
carry = 1
res.append(0)
}else {
carry = 0
res.append(sum)
}
index -= 1
}
return res.reversed()
}
Time Complexity = O(n)
Space Complexity = O(n)
8.0 Move Zeroes
๊ณ ๋ฏผ
- Extra Memory ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ Inplace ๋ฐฉ์์ผ๋ก ์๊ณ ๋ฆฌ์ฆ์ ์ด๋ป๊ฒ ๊ตฌํ ํ ๊น?
- O(N) ์ผ๋ก ๊ตฌํ ํด๋ณด์
์ ๊ทผ ๋ฐฉ์
- ๋ฐฐ์ด์ ์ํ ํ ๋ ํ์ํ
i
์ 0 ์ ์์น๋ฅผ ๊ฐ๋ฅด์ผ์คpointerToZero
, Two Pointer ๋ฅผ ์ฌ์ฉํ๋ค. - ๋ฐฐ์ด์ ์ํ ํ ๋
i
๋ฒ์งธ ์์๊ฐ 0 ์ด ์๋์ ๋ค์ ์์๋ก ๋์ด ๊ฐ๋ค. ์ด๋ก์จ ๋ฐฐ์ด์ ์ฒซ 0 ์ i ๋ฒ์งธ ์์์ ๋ฐ๊ฟ์ ์๊ฒ ๋๋ค.
๊ฒฐ๊ณผ
func moveZeroes(_ nums: inout [Int]) {
var pointerToZero = 0
for i in 0..<nums.count {
if nums[i] == 0 {continue}
nums.swapAt(i, pointerToZero)
pointerToZero += 1
}
}
Time Complexity = O(n)
Space Complexity = O(1)
9.0 Two Sum
๊ณ ๋ฏผ
- ์๊ฐ๋ณต์ก๋
O(n^2)
์ดํ๋ก ๋ฌธ์ ๋ฅผ ํ์ ์์๊น?
์ ๊ทผ ๋ฐฉ๋ฒ
- ๋์ ๋๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค ํ๋ค.
- nums ๋ฅผ ์ํ ํ๋ฉด์
Target - nums[i]
์ ๋์ ๋๋ฆฌ์ Key ๋ก, value ๋ i ๊ฐ์ผ๋ก ํ ๋นํ๋ค. - ๋์
๋๋ฆฌ์ key ๊ฐ์ nums[i] ์ ์์๊ฐ ์๋์ง ํ์ธํ๋ค. ์ด๊ฐ์ x ๋ผ๊ณ ํ๋ค๋ฉด,
Target - nums[i] = x
,x + nums[i] = Target
์ด ์ฑ์ฌํ๋ค. - i ์ ์ ์ฅ๋์ด ์๋ ๋์ ๋๋ฆฌ์ value ๊ฐ์ ๋ฆฌํด ํ๋ค.
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var dict: [Int:Int] = []
for (index, value) in nums.enumerated() {
guard let matchedRemainingIndex = dict[value] else {
dict.updateValue(index, forKey: target - value)
continue
}
return [index, matchedRemainingIndex]
}
}
Time Complexity = O(n)
Space Complexity = O(n)
10.0 Valid Sudoku
๊ณ ๋ฏผ
๋ฌธ์ ์์ฝ
: ์ด๋ฌธ์ ๋ valid ํ ์ค๋์ฟ ์ธ๊ฒ์ ํ์ธํ๊ธฐ ์ํด์ row, column, square(3x3) ์์ ์๋ ์์๋ค์ด 1~9 ๊น์ง ๊ฒน์น๋์ง ํ์ธํ๋ ๋ฌธ์ ์๋ค.- 1.0 ์ค๋์ฟ ๋ฐฐ์ด ์ํ ๋ฐฉ๋ฒ
- 2.0 ์ด๋ค ์๋ฃ๊ตฌ์กฐ๋ก ์ค๋ณต ํ์ธ์ ํด์ค๊น?
- 3.0 row, column, square ๋ฅผ ์ฒดํฌํด์ผํ๋๋ฐ ์ด๋ค ์์๋ก ์ฒดํฌ๋ฅผ ํด์ค๊น?
- 4.0 square ์ฒดํฌ๋ฅผ ์ด๋ค์์ผ๋ก ํด์ผํ๋?
ํด๊ฒฐ
- 1.0 ์ค๋์ฟ ๋ฐฐ์ด ์ํ ๋ฐฉ๋ฒ - ์๋์ ๊ฐ์ด ์ค๋์ฟ ๋ฐฐ์ด์ด ์ฃผ์ด์ง๋ฉด ๊ฐ์ฅ ์ฝ๊ฒ ๋ชจ๋ ๋ฐฐ์ด์ ์์๋ฅผ ์ํํ ์ ์๋ ๊ฐ์ฅ ์ฝ๊ณ ์ง๊ด์ ์ธ ๋ฐฉ๋ฒ์ brute force ๋ฐฉ๋ฒ์ผ๋ก ์งํํ๋๊ฒ์ด์๋ค. - row, column ์ ์์๋ฅผ ์ง์ ํ๊ธฐ ์ํด i ๋ฒ์งธ row ๋ฅผ ๊ธฐ์ค์ผ๋ก row ์ ์๋ ์์๋ค์ j ๋ก ์ง์ ํ๋ค.
-
2.0 ์ด๋ค ์๋ฃ๊ตฌ์กฐ๋ก ์ค๋ณต ํ์ธ์ ํด์ค๊น?
- swift ์๋ array, set, dictionary ๋ฅผ ์ด์ฉํ์ฌ ์ค๋ณต๋ ์์๊ฐ ์๋์ง ํ์ธํ๋
contains
๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค. - ์ด์ค ์ต์ ์ time complexity ๋ฅผ ๊ฐ๋ ์๋ฃ๊ตฌ์กฐ๋ก ์ ํํ๋ค.
- array: O(n)
- set: O(1)
- dictionary: O(1)
set
๊ณผdictionary
๋hashing
์ ์ฌ์ฉํด O(1) ์ ์๊ฐ๋ณต์ก๋๋ก ์ค๋ณต๋ ์์๋ฅผ ์ฐพ์์ ์์๋ค. ์ด์คdictionary
๋key
,value
๊ฐ์ ํ ๋นํด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์set
๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ง์ด ์ฌ์ฉํ๊ฒ ๋๋ค.- ๋ฐ๋ผ์
set
์ผ๋ก ์ค๋ณตํ์ธ์ ์งํํ๋ค.
- swift ์๋ array, set, dictionary ๋ฅผ ์ด์ฉํ์ฌ ์ค๋ณต๋ ์์๊ฐ ์๋์ง ํ์ธํ๋
-
3.0 row, column, square ๋ฅผ ์ฒดํฌํด์ผํ๋๋ฐ ์ด๋ค ์์๋ก ์ฒดํฌ๋ฅผ ํด์ค๊น?
- ์๊ฐํด๋ณด๋ row, column, square ๋ฅผ ์ฒดํฌํ๋ ์์์ ์๊ด์์ด ์ค๋ณต์์๊ฐ ์๋ค๋ฉด false ๋ฅผ ๋ฐํํด์ฃผ๋ฉด ๋๋ค.
-
4.0 square ์ฒดํฌ๋ฅผ ์ด๋ค์์ผ๋ก ํด์ผํ๋?
-
์ํํ๋ ๋ฐฉ๋ฒ์ผ๋ก brute force ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ squareSet ์ ๋ค์ด๊ฐ ์์๋ค์ innerloop ์์ ์ง์ ํด์ฃผ์ด์ผํ๋ค.
-
์ด๋ innerloop ์ row ์์๋ค์ ์ํํ๊ธฐ ๋๋ฌธ์ row ์์๋ค์ 3๊ฐ ์ฉ ๋๋์ด์ sqaureSet ์ ํ ๋นํด์ฃผ๋๊ฒ ์ง๊ด์ ์ด๋ผ ์๊ฐํ๋ค.
-
ํ ๋นํด์ฃผ๋ ค๋ ๊ณผ์ ์์ ๊ฒช์ ๋ฌธ์ ๋ row ์ ์์๋ฅผ ์ํํ ๋ i ๋ฒ์งธ ์๋ row ์ ์๋ ๋ชจ๋ ์์๋ค์ sqaureSet ์ ๋ฃ์ด์ฃผ์ด์ผ ํ์๋ค.
- ๊ธฐ์กด์ ์๊ฐํ๋ ์ค๋ณตํ์ธ ๋ฐฉ๋ฒ
-> ๋ฌธ์ : loop ์์ i๋ฒ์จฐ row ์์ ์ ์ฒด๋ฅผ ์ํ ํ๊ธฐ ๋๋ฌธ์ squareSet ํ๋์ฉ ๊ฒ์ฌํ๋๊ฒ์ ๋ถ๊ฐ๋ฅ.
- row ์ ์๋ ๋ชจ๋ ์์๋ค์ sqaureSet ์ ์ง์ด ๋ฃ๊ธฐ ์ํด์ 3๊ฐ์ sqaureSet ์ด ํ์ํ๋ค.
๋ฐ๋ผ์
var squareSet = Array(repeating: Set<Character>(), count: (board.count/3))
์ ๊ฐ์ด squareSet ์ ์ด๊ธฐํ ํด์ฃผ์๊ณ i๋ฒ์งธ row ๋ฅผ ์ํ ํ ๋ 3๊ฐ์ฉ ์์๋ฅผ ๋์ด์ sqaureSet ์ ํ ๋นํด์ฃผ์๋ค.
๊ฒฐ๊ณผ
-
func isValidSudoku(_ board: [[Character]]) -> Bool {
var itemCount = 0
var squareSet = Array(repeating: Set<Character>(), count: (board.count/3))
for i in 0..<board.count {
var rowCheckSet: Set<Character> = Set<Character>()
var colCheckSet: Set<Character> = Set<Character>()
// Checking Squares, Rows, Column in sequence
for j in 0..<board[i].count {
let rowElement = board[i][j]
let colElement = board[j][i]
itemCount += 1
let index = j/3
//Checking Squares
if checkDuplicate(val: rowElement, on: squareSet[index]) {
squareSet[index].insert(rowElement)
}else {
print("detected Duplicates within the square!")
return false
}
//Checking Rows
if checkDuplicate(val: rowElement, on: rowCheckSet) {
rowCheckSet.insert(rowElement)
}else {
print("detected Duplicates within the rows!")
return false
}
//Checking Columns
if checkDuplicate(val: colElement, on: colCheckSet) {
colCheckSet.insert(colElement)
}else {
print("detected Duplicates within the columns!")
return false
}
}
//3๊ฐ์ rows ์ฉ ์๋ผ์ ์งํ.
if itemCount % 27 == 0 {
for i in 0..<squareSet.count{
squareSet[i].removeAll()
}
}
rowCheckSet.removeAll()
colCheckSet.removeAll()
}
return true
}
func checkDuplicate(val: Character, on set: Set<Character>) -> Bool {
if val == "." {return true}
else if set.contains(val){
return false
}
return true
}
Time Complexity = O(n^2)
Space Complexity = O(n)
11.0 Rotate Image
๊ณ ๋ฏผ
- ์ด๋ค์์ผ๋ก element ์ ํ์ ์์ ๋ฐฐ์นํด์ผํ ์ง ๊ณ ๋ฏผ
- n*n ์ ๋ฐฐ์ด์ ์ด๋ป๊ฒ ์ํ ํด์ผํ ์ง ๊ณ ๋ฏผ
- Element ํ์ ์๊ณ ๋ฆฌ์ฆ ์ธ์ฐ๊ธฐ
ํด๊ฒฐ
1.0 ์ด๋ค์์ผ๋ก element ์ ํ์ ์์ ๋ฐฐ์นํด์ผํ ์ง ๊ณ ๋ฏผ ์ ๋ฐ์ ์ธ ๋ฐฐ์ด์ ์์๋ฅผ ๋ฐฐ์นํ๋๊ฒ์ ์๋์ ๊ทธ๋ํ์ฒ๋ผ i ๋ฒ์งธ row ๋ฅผ ์ํ ํ๋ฉด์ ๊ฐ๊ฐ์ ์์๋ฅผ ๊ฐ๋ณ์ ๊ณ์ฐ๋ ์ขํ์ ๊ฐ์ ํ ๋นํ๋ค.
2.0 n*n ์ ๋ฐฐ์ด์ ์ด๋ป๊ฒ ์ํ ํด์ผํ ์ง ๊ณ ๋ฏผ
-
์ผ๋จ i ๋ฒ์งธ row ๋ฅผ ์ํ ํ๊ณ , j ๋ฒ์งธ ์์๋ฅผ ์ํ ํ outter loop ๊ณผ inner loop ์ด ํ์ํ๋ค.
-
outer loop
: n ๊ฐ์ row ๋ฅผ ์ด๋ป๊ฒ ์ํ ํ ๊น?- ํ์ํ row ์ ๊ฐ์๋ ๋ช๊ฐ ์ธ๊ฐ?
- 4x4 ๋ฐฐ์ด ์ผ๋๋ฅผ ๊ฐ์ ํด๋ณด์
- ์๋ ๊ทธ๋ฆผ์ฒ๋ผ 2๊ฐ์ ์ฌ๊ฐํ์ผ๋ก ๋๋์๊ฐ ์๋ค. ๊ทธ๋ฆฌ๊ณ row ์ ์ ๋ณด๋ง์ผ๋ก ๋ชจ๋ ์์๋ฅผ ๋๋ฉด์ rotate ์ด ๊ฐ๋ฅํ๋ค.
- n ์ด 4 ์ผ๋,
i = 0,1
์ ๊ทธ๋ฆผ์ฒ๋ผ ๋๋ฒ์ row ๋ฅผ ์ํ ํ ๊ฒ์ด๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ค๋ฅธ ์ผ์ด์ค๋ฅผ ํ๋ฒ ์๊ฐํด๋ณด๊ณ outer loop ๊ณต์์ ์ธ์๋ณด์.
n i 1 (0) 2 (0) 3 (0,1) 4 (0,1) 5 (0,1) 6 (0,1,2) 10 (0,1,2,3,4) - ์ ํ
์ด๋ธ n ๊ณผ i ๊ฐ์ ๋ถ์ํด๋ณด๋ฉด
i = 0..<N/2
๊ณต์์ ์ถ๋ก ํ ์ ์์๋ค. inner loop
: ๋ช๊ฐ์ ์์๋ฅผ ๊ฐ row ์์ ์ํ ํด์ผํ ๊น?- ๋๊ฐ์ ์ฌ๊ฐํ์ผ๋ก ๋๋๋ฉด ์ธ๋ถ์ ์ฌ๊ฐํ์
0 ๋ถํฐ N-1
๊น์ง์ indexing ์ด ํ์ํ๋ค. - ๋ด๋ถ ์ฌ๊ฐํ์์๋ ์ธ๋ถ์ฌ๊ฐํ์์ ํ์ ํ ๊ฐ์ ๊ฑด๋ค์ด์ง ๋ง์์ผํ๋ค.
j = N-i-1
์ inner loop ์ ํ ๋นํด์ฃผ๋ฉด ์ฃผ์ด์ง ์๊ตฌ์ฌํญ์ ๋ง์ถ์ด j ์์์ ์ํ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ ์์๋ค.
- ํ์ํ row ์ ๊ฐ์๋ ๋ช๊ฐ ์ธ๊ฐ?
3.0 Element ํ์ ์๊ณ ๋ฆฌ์ฆ ์ธ์ฐ๊ธฐ
- 1.0 ์์ ์ฐพ์ ๋ฐฉ๋ฒ์ ์ด๋ค ๋ก์ง์ ์ฌ์ฉํด์ ๊ตฌํํด์ผํ ๊น?
- ์ผ๋จ ์ ์ฒด์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ํ๋ฆ์ ์๋์ ๊ฐ๋ค.
ex) i = 0, j = 0
//Top ์ ์๋ ์์๋ฅผ temp ์ ์ ์ฅ
let temp = matrix[0][0]
//Top ์ ์๋ ์์์ ํ ๋น
matrix[0][0] = matrix[3][0]
//Left ์ ์๋ ์์์ ํ ๋น
matrix[3][0] = matrix[3][3]
//Bottom ์ ์๋ ์์์ ํ ๋น
matrix[3][3] = matrix[0][3]
//Right ์ ์๋ ์์์ ํ ๋น
matrix[0][3] = temp
- ์ ์ฝ๋๋ฅผ ๋ชจ๋ i,j ์ ๊ฐ์ด ๋ค์ด์ฌ๋ rotate ๋ ์๋ฆฌ์ index ๋ฅผ ๊ณ์ฐํด์ผํ๋๋ฐ, ๋ช๊ฐ์ ์์๋ฅผ ๋ง๋ค์ด ํจํด์ ์ฐพ๊ณ ๋ก์ง์ ๋ง๋ค์ด๋ณด์
// i = 0, j = 0
//Top ์ ์๋ ์์๋ฅผ temp ์ ์ ์ฅ
let temp = matrix[0][0]
//Top ์ ์๋ ์์์ ํ ๋น
matrix[0][0] = matrix[3][0]
//Left ์ ์๋ ์์์ ํ ๋น
matrix[3][0] = matrix[3][3]
//Bottom ์ ์๋ ์์์ ํ ๋น
matrix[3][3] = matrix[0][3]
//Right ์ ์๋ ์์์ ํ ๋น
matrix[0][3] = temp
// i = 0, j = 1
//Top ์ ์๋ ์์๋ฅผ temp ์ ์ ์ฅ
let temp = matrix[0][1]
//Top ์ ์๋ ์์์ ํ ๋น
matrix[0][1] = matrix[2][0]
//Left ์ ์๋ ์์์ ํ ๋น
matrix[2][0] = matrix[3][2]
//Bottom ์ ์๋ ์์์ ํ ๋น
matrix[3][2] = matrix[1][3]
//Right ์ ์๋ ์์์ ํ ๋น
matrix[1][3] = temp
//i = 0, j = 2
//Top ์ ์๋ ์์์ ํ ๋น
matrix[0][2] = matrix[1][0]
//Left ์ ์๋ ์์์ ํ ๋น
matrix[1][0] = matrix[3][1]
//Bottom ์ ์๋ ์์์ ํ ๋น
matrix[3][1] = matrix[2][3]
//Right ์ ์๋ ์์์ ํ ๋น
matrix[2][3] = temp
ํด๊ฒฐ
- ์ ํจํด์ ๊ฐ๊ฐ ์ side ๋ง๋ค ๋ถ์ํ๋ฉด ์๋์ ๊ฐ์ ๋ก์ง์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
func rotate(_ matrix: inout [[Int]]) {
let N = matrix.count
for i in 0..<N/2 {
for j in i..<N-1-i {
//Store the First element in square
let temp = matrix[i][j]
//Allocate top Element
matrix[i][j] = matrix[N-j-1][i]
//Allocate Leftside Element
matrix[N-j-1][i] = matrix[N-i-1][N-j-1]
//Allocate bottom element
matrix[N-i-1][N-j-1] = matrix[j][N-i-1]
//Allocate rightside element
matrix[j][N-i-1] = temp
}
}
}
Time complexity = O(n^2)
Space complexity = O(n)
1.0 Reverse String
๊ณ ๋ฏผ
- reverse ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์๊น?
ํด๊ฒฐ
- two Pointer ๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ ํ๋ค.
- ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์์ ๋ถํฐ ๊ฐ๋ฅดํค๋ ํฌ์ธํฐ๋ฅผ
pointer
๋ผ๊ณ ๋ถ๋ ๋ค. - ๋ฐฐ์ด์ ๋ง์ง๋ง ์์ ๋ถํฐ ๊ฐ๋ฅดํค๋ ํฌ์ธํฐ๋ฅผ
index
๋ผ๊ณ ๋ถ๋ ๋ค. - while ๋ฌธ์ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ์๋ ํ๋ค.
- ์์๋ก ์ฃผ์ด์ง ๋ฐฐ์ด์ ๋ฌธ์ฅ์
["H","E","L","L","O"]
-> ๊ธธ์ด๊ฐ 5์ธ ๋ฐฐ์ด์ด์๋ค. - while ์ ์ปจ๋์ ์ ์๋์ ๊ฐ์ด ์ฃผ์๊ณ , ์์๋ก์ฃผ์ด์ง ๋ฐฐ์ด์ ํด๊ฒฐํ ์ ์์๋ค.
var pointer = 0 var index = arr.count - 1 while index != pointer { arr.swapAt(index, pointer) index -= 1 pointer += 1 } }
- ํ์ง๋ง ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ ํ์ ์ผ๋ index ์ pointer ๊ฐ ๊ฐ์์ง๋ ์์ ์ด ์๊ธฐ ๋๋ฌธ์ while ๋ฌธ ์ปจ๋์ ์ ์๋์ ๊ฐ์ด ์์ ํด์ฃผ์๋ค.
- ์์๋ก ์ฃผ์ด์ง ๋ฐฐ์ด์ ๋ฌธ์ฅ์
๊ฒฐ๊ณผ
var pointer = 0
var index = arr.count - 1
while index >= pointer {
arr.swapAt(index, pointer)
index -= 1
pointer += 1
}
}
Time complexity = O(logn)
Space complexity = O(1)
2.0 Reverse Integer
๊ณ ๋ฏผ
- 10 ๋๋ ๋๋จธ์ง ๊ฐ์ ์ด๋ป๊ฒ ํ๋ฉด ์๋ง์ ์๋ฆฌ์์ ํ ๋นํ ์ ์์๊น?
ํด๊ฒฐ
- [String] ์ ์ฌ์ฉํด์ 1์ ์๋ฆฌ์์ ๋ถํฐ ๊ณ์ฐ๋ ๋๋จธ์ง๊ฐ์ append ์์ผ์ค๋ค์ joined ํด์ค๋ค.
func reverse(_ x: Int) -> Int {
var val = abs(x)
let sign = x > 0 ? 1:-1
var digits:[String] = []
while val != 0 {
let remainder = val % 10
val = val / 10
digits.append(String(remainder)!)
}
let reversedValue = signed * Int(digits.joined())!
}
- ๋ฌธ์ : Extra memory ๋ฅผ ์ฌ์ฉํจ.
reversedValue
๋ฅผ ๋จผ์ ์ ์ธํ๊ณ iteration ๋ง๋ค 10 ์ ๊ณฑํด์ฃผ๊ณ ๋๋จธ์ง ๊ฐ์ ๋ํด์ฃผ๋ ๋ก์ง์ ์ ์ฉ
๊ฒฐ๊ณผ
func reverse(_ x: Int) -> Int {
var val = abs(x)
let sign = x > 0 ? 1:-1
var reversedValue = 0
while val != 0 {
let remainder = val % 10
val = val / 10
reversedValue = reversedValue * 10 + remainder
}
reversedValue *= sign
if reversedValue >= Int32.max-1 || reversedValue <= Int32.min
{return 0}
return reversedValue
}
Time complexity = O(n)
Space complexity = O(n)
3.0 First Unique Character in a String
๊ณ ๋ฏผ
- ์ค๋ณต๋ ์์์ ๊ฐ์๋ฅผ ์ด๋ป๊ฒ count ํ ๊น?
ํด๊ฒฐ
- ๋์ ๋๋ฆฌ๋ฅผ ์ด์ฉํด ๋ฌธ์ ํด๊ฒฐ
1.0
s
๋ฅผ ์ํํ์ฌ dictionary ์key = letter
,value = count
๋ฅผ ํ ๋น.
2.0
s
๋ฅผ ๋ค์ํ๋ฒ ์ํํ์ฌ ๊ฐ ์์๋ฅผ dictionary ์ key ๊ฐ์ ๋ฃ์ด ์ค๋ณต๋ count ๊ฐ์ ๋น๊ตํ๋ค.
3.0 count ๊ฐ์ด 1์ธ index ๋ฅผ ๋ฆฌํด
๊ฒฐ๊ณผ
func firstUniqChar(_ s: String) -> Int {
var dict:[Character:Int] = [:]
for character in s {
if dict[character] != nil, let count = dict[character] {
dict.updateValue(count + 1, forKey: character)
}else {
dict.updateValue(1, forKey: character)
}
}
for (index,character) in s.enumerated() {
if dict[character] == 1 {
return index
}
}
return -1
}
Time Complexity = O(n)
Space Complexity = O(n)
4.0 Valid Anagram
๊ณ ๋ฏผ
- ์ด๋ป๊ฒ ์ฃผ์ด์ง ๋๊ฐ์ string ์์ ๊ฐ๊ฐ์ character ์ผ์นํ๋์ง ์์ ์์๊น?
ํด๊ฒฐ
- Set ์ ์ด์ฉํด์ ๋ฌธ์ ๋ฅผ ํ๋ ค๊ณ ํ์ผ๋, ์ค๋ณต๋ character ์ ๊ฐ์๋ ์ผ์นํด์ผํ๋ค๋๊ฒ์ ๊นจ๋ซ๊ณ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ์๋ดค๋ค.
- Character ๋ ๊ณ ์ ํ unicode ๋ก ์ด๋ฃจ์์ ธ์๋ค.
- ์ด ๊ฐ์ ์ฌ์ฉํด์ ๊ฐ ๋จ์ด๋ฅผ sort ํด์ค๋ค์ ๋น๊ตํ๋ฉด ๊ฐ string ์ ๊ตฌ์ฑํ๋ characters ๊ฐ ์ผ์นํ๋์ง ์์ ์์ง ์์๊น ํด์ ์๋ํจ.
๊ฒฐ๊ณผ
func isAnagram(_ s: String, _ t: String) -> Bool {
return s.sorted(by: {$0 < $1}) == t.sorted(by: {$0 < $1})
}
TimeComplexity = O(NlogN)
SpaceComplexity = O(1)
5.0 Valid Palindrome
๊ณ ๋ฏผ
- ์ด๋ป๊ฒ ์ํ๋ฒณ ๊ณผ ์ซ์๋ฅผ ํํฐ๋ง ํด์ผํ๋?
ํด๊ฒฐ
CharacterSet
์alphanumerics
์ ์ฌ์ฉํด์ ํํฐ๋ง ๊ณผ์ ์ ๊ฑฐ์ณ ์ํ๋ฒณ ๊ณผ ์ซ์๋ฅผ ํํฐ๋ง ํด์ค๋ค.- ์ด๋ ์ฃผ์ด์ง ์คํธ๋ง์ unicodeScalars ๋ก ๋ณํ ์์ผ์ฃผ์ด ํํฐ๋ง ํด์ฃผ์ด์ผํ๋ค.
- ์ฐธ์กฐ
๊ฒฐ๊ณผ
func isPalindrome(_ s: String) -> Bool {
let result = String(s.unicodeScalars.filter({CharacterSet.alphanumerics.contains($0)})).map({$0.lowercased()})
let reversed = result.reversed()
return result.joined() == reversed.joined()
}
Time Complexity = O(n)
Space Complexity = O(1)
6.0 String to Integer (atoi)
๊ณ ๋ฏผ
' '
,'+'
,'-'
, and'.'
๊ฐ๋ค์ ์ด๋ป๊ฒ ํํฐ๋ง ํด์ค๊น?
ํด๊ฒฐ
- 1.0 ๋ฌธ์์ด ์์
' '
์ ์์ ์ฃผ๊ธฐ ์ํดtrimmingCharacters
์ ์ฌ์ฉํด์ whiteSpace ๋ค์ ์ ๊ฑฐํ๋ค. - 2.0 ๋ฌธ์์ด ์์
'+'
,'-'
๋ฅผ ํํฐ๋งํด์ฃผ๊ธฐ ์ํดprefix()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค. - 3.0 ๋๋จธ์ง ๋ฌธ์์ด์์ ์ ์ผ ์์ ์์นํ ์ซ์๋ง ๋ฝ์๋ด์ผํ๋ค. -> ๋ชจ๋ ์ซ์๋ Ascii code ๋ก ์์ฝ๊ฒ ๊ตฌ๋ณํ ์ ์์ผ๋ฏ๋ก
48~57
๊น์ง์ ascii value ๋ง ๊บผ๋ด์ ๊ณ์ฐํด์ฃผ์๋ค.
func myAtoi(_ s: String) -> Int {
var removedWhiteSpace = s.trimmingCharacters(in: CharacterSet.whitespaces)
var sign = 1
var value = 0
if removedWhiteSpace.hasPrefix("-"){
sign = -1
removedWhiteSpace.removeFirst()
}
else if removedWhiteSpace.hasPrefix("+"){
sign = 1
removedWhiteSpace.removeFirst()
}
for char in removedWhiteSpace {
if char.asciiValue! >= 48 && char.asciiValue! <= 57 && value < Int32.max && value > Int32.min {
value = value * 10 + Int(String(char))!
}else {
break
}
}
var res = sign * value
if res > Int32.max - 1 {
res = Int(Int32.max)
}
else if res < Int32.min {
res = Int(Int32.min)
}
return res
}
Time Complexity = O(n)
Space Complexity = O(n)
7.0 strStr
๊ณ ๋ฏผ
- needle ์ด ์ด๋ป๊ฒ haystack ์์ ์๋์ง ํ์ธํ๊ณ ์ผ์นํ๋ ์ฒซ๋ฒ์จฐ ์ธ๋ฑ์ค ๋ฅผ ๋ฐํํด์ค๊น?
ํด๊ฒฐ
haystack
์ ์ํ ํ๋ฉด์hayStack.firstIndex + i
์(haystack.startIndex, offsetBy: needle.count - 1 + i)
start, end ์ธ๋ฑ์ค๋ฅผ ๊ณ์ฐํด์ค๋ค.- ๊ณ์ฐ๋ start, end ๋ฅผ
hayStack[start...end] == needle
์ธ์ง ํ์ธํ๊ณ ๋ง์ผ๋ฉดi
๋ฅผ ๋ฐํํ๋ ๋ก์ง์ ๊ตฌ์ฑํด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
๊ฒฐ๊ณผ
func strStr(_ haystack: String, _ needle: String) -> Int {
if haystack.count < needle.count {return -1}
for i in 0...haystack.count - needle.count {
let newStartIndex = haystack.index(haystack.startIndex, offsetBy: i)
let newEndIndex = haystack.index(haystack.startIndex, offsetBy: needle.count - 1 + i)
if haystack[newStartIndex...newEndIndex] == needle {
return i
}
}
return -1
}
Time complexity = O(n)
Space complexity = O(1)
8.0 Longest Common Prefix
ํด๊ฒฐ
- swift foundation ์ ์๋
commonPrefix
๋ฉ์๋ ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์ ํด๊ฒฐ
๊ฒฐ๊ณผ
func longestCommonPrefix(_ strs: [String]) -> String {
var prefix = strs.first!
for i in 1..<strs.count {
prefix = prefix.commonPrefix(with: strs[i])
}
return prefix
}
Time Complexity = O(n)
Space Complexity = O(n)
1.0 Delete Node in a Linked List
๊ณ ๋ฏผ
- ์ฃผ์ด์ง LikedList ์ ํน์ node ๋ฅผ ์ง์ฐ๋ฉด ๋๋๋ฐ ํจ์์ input ์ linkedList ๋ฐ์ ์์ด์ ๋นํฉํจ
ํด๊ฒฐ
- LikedList ์ ํน์ node ๊ฐ ์ฃผ์ด์ง๋๊ฒ ์๋๋ผ ์ด ํจ์๋ฅผ ๋ฐ์์ ์ฌ์ฉํ์๋ ํจ์์์ ์ฃผ์ด์ง ๋ ธ๋๋ฅผ ๋ฆฌ์คํธ์์ ์ญ์ ํ๋ผ๋ ๋ป์ด์๋ค.
- ์ฃผ์ด์ง ๋ ธ๋์ ๊ฐ์ ๊ทธ ๋ค์ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ค.
- ์ฃผ์ด์ง ๋
ธ๋์ nextNode ๋
node.next.next
๋ฅผ ๊ฐ๋ฅดํค๊ณ ์๋๊ฒ์ด๋ค.
func deleteNode(_ node: ListNode?) {
node?.val = (node?.next!.val)!
node?.next = node?.next?.next
}
Time complexity = O(1)
Space complexity = O(1)
2.0 Remove Nth Node From End of List
๊ณ ๋ฏผ
- ์ด๋ป๊ฒ linked list ์ ๋ง์ง๋ง ๋ถํฐ n ๋ฒ์งธ์ ์์๋ฅผ ์ง์ธ์ ์์๋ผ?
- ์ฐ๊ฒฐ๋ list ์ ๋ค์ ๋ ธ๋๋ฅผ ์ด๋ป๊ฒ ์์๋ผ๊น?
- ์ด๋ป๊ฒ list ์ ์ฐ๊ฒฐ์ ๋์ด์ค๊น?
ํด๊ฒฐ
- ์ด๋ป๊ฒ linked list ์ ๋ง์ง๋ง ๋ถํฐ n ๋ฒ์งธ์ ์์๋ฅผ ์ง์ธ์ ์์๊น?
-> node ์ ๋ค์ ์์๊ฐ nil ์ผ๋๊น์ง ์ํ ํ๋ฉฐ indexCnt
๋ฅผ ๊ธฐ๋กํด๋์๋ค.
- ์ฐ๊ฒฐ๋ list ์ ๋ค์ ๋ ธ๋๋ฅผ ์ด๋ป๊ฒ ์์๋ผ๊น?
-> class ๋ก ์์ฑ๋ list ๋ head ์ ์ฃผ์๋ฅผ ํ๋ curr
, prev
, ๋๊ฐ์ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ ๊ฐ๋ฅดํค๊ณ ์๋ ๋
ธ๋, ์ด์ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํค๊ณ ์๋ ๋ณ์๋ฅผ ๋ง๋ค์ด์ฃผ์๋ค.
-> for loop ์ indexCnt-n
๋ฒ๊น์ง ์ํํ๋ฉฐ prev ๋ curr ๋
ธ๋๋ฅผ, curr ์ ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํคํฌ์ ์๋๋ก ๊ตฌํ.
- ์ด๋ป๊ฒ list ์ ์ฐ๊ฒฐ์ ๋์ด์ค๊น? -> ์๋์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ์ด์ ๋ ธ๋์ ๋ค์ ๋ ธ๋๋ฅผ ํ์ฌ๋ ธ๋์ ๋ค์ ๋ ธ๋๋ก ์ฐ๊ฒฐ์์ผ์ฃผ๊ณ , ํ์ฌ ๋ ธ๋๋ ์ญ์ ๋์ด์ผํ ๋ ธ๋์ด๊ธฐ ๋๋ฌธ์ next ๊ฐ์ 0 ์ผ๋ก ๋ง๋ค์ด ์ฃผ์ด list ์ ์ฐ๊ฒฐ ์ ๋๋๋ค.
-> ์ ์ผ ์ฒ์ ์์๋ฅผ ์ญ์ ํด์ผํ๋ test case ๊ฐ ์์๋๋ฐ, indexCnt == n
์ผ๋ ํ์ฌ head ๋ฅผ ๊ฐ๋ฅดํค๊ณ ์๋ curr ํฌ์ธํฐ์ ๋ค์ ๋
ธ๋๋ฅผ ๋ค์ ๋
ธ๋๋ก ์ค์ ํ๋ค curr ๋ฅผ ๋ฐํํด์ฃผ๋ฉด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
๊ฒฐ๊ณผ
func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
var indexCnt = 1
var counter = head
var curr = head
var prev: ListNode?
//list ์ ๊ฐ์๊ฐ ๋ช๊ฐ์ธ์ง ํ์ธ
while counter?.next != nil {
counter = counter?.next
indexCnt += 1
}
//indexCnt ์ n ๊ฐ์ด ๊ฐ๋ค๋ฉด ์ ์ผ ์ฒซ๋ฒ์งธ ์์๋ฅผ ์ง์ด๋ค๋ ๋ป.
if indexCnt == n {
curr = curr?.next
return curr
}
//prev, curr ํฌ์ธํฐ ์ด๋
for _ in 0..<indexCnt-n {
prev = curr
curr = curr?.next
// print(curr?.val)
}
//prev ๋ฅผ curr ๋ค์ ๋
ธ๋์ ์ฐ๊ฒฐ ํ๋ค curr.next ๋ฅผ ๋์ด์ค๋ค.
prev?.next = curr?.next
curr?.next = nil
return head
}
Time complextiy = O(n)
Space Complexity = O(1)
3.0 Reverse Linked List
๊ณ ๋ฏผ
- ๋ฆฌ์คํธ๋ฅผ ์ํ ํ๋ฉด์ pointer ๋ฅผ ์ด๋ค์์ผ๋ก ํ์ฉํ์ฌ ๋ค์ง์ด์ง list ํํ๋ฅผ ๋ง๋ค์ ์์๊น?
ํด๊ฒฐ
- 3 pointers ๋ฅผ ์ด์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ.
- ๋ค์ง์ด์ง ๋ฆฌ์คํธ๋ฅผ ๊ธฐ๋กํ Pointer =
reversedList
- ํ์ฌ ๋ ธ๋๋ฅผ ๊ฐ๋ฅดํค๋ Pointer =
curr
- ๋ค์๋ฒ์งธ ๋ ธ๋๋ฅผ ๊ฐ๋ฅดํค๋ Pointer =
nextNode
- ๋ฆฌ์คํธ ๋ค์ง๊ธฐ ์๊ณ ๋ฆฌ์ฆ
- ํ์ฌ ๋ ธ๋์ link ๋ฅผ ๋์ด ์ฃผ๊ณ , ์ด์ ์ ๋ ธ๋ ๋ฅผ next ๋ก ์ค์ ํด์ฃผ๋ฉฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ.
- 1.0
nextNode
์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผreversedList
์ ํ ๋นํด์ฃผ๋ฉฐ ๊ธฐ์กดcurr
๋ ธ๋์ ๋งํฌ์ ๋ฐฉํฅ์ ๋ฐ๊ฟ.- 2.0
reversedList
๋ ธ๋์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผcurr
๋ ธ๋๋ก ์ ๋ฐ์ดํธ ์ํด.- 3.0
curr
๋ ธ๋์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผnextNode
๋ก ํ ๋น.- 4.0
nextNode
์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผcurr.next
์ฃผ์๋ก ํ ๋น์ํด- 5.0
curr
๋ ธ๋๊ฐ nill ์ ๊ฐ๋ฅดํฌ๋๊น์ง ๋ฐ๋ณต.
- ์ ์ฒด์ ์ธ ํฌ์ธํฐ ์งํ ๋ฐฉํฅ ๋ฐ ์ฒ์ ํฌ์ธํฐ๋ค์ด ๊ฐ๋ฅดํค๊ณ ์๋ ๋ ธ๋ ์ฃผ์
- ํฌ์ธํฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ์ ๋ฐ์ดํธ ๋ฐ ์๊ณ ๋ฆฌ์ฆ ์งํ์์ ๋์ํ
๊ฒฐ๊ณผ
func reverseList(_ head: ListNode?) -> ListNode? {
//revseredList ๋ ์ด๊ธฐ๋ก Nill ์ ์ฃผ์ ๊ฐ์ ๊ฐ์ง๊ณ ์์.
var reversedList: ListNode? = nil
//curr ์ head ์ ์ฒซ๋ฒ์จฐ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํค๊ณ ์์.
var curr = head
//nextNode ๋ head ์ ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํด.
var nextNode = curr?.next
while curr != nil {
//curr ์ ๋ค์ ์์์ ์ฃผ์ ๊ฐ์ temp ๋ก ์ง์
curr?.next = reversedList
reversedList = curr
curr = nextNode
nextNode = curr?.next
}
return reversedList
}
Time complexity = O(n)
Space Complexity = O(1)
4.0 Merge Two Sorted Lists
๊ณ ๋ฏผ
list1
ํน์list1
์ ๊ฐ์ ๋น๊ตํ๋ ์ค์ ๋์ค์ ํ๋์ ๊ฐ์ด ์์ ๊ฒฝ์ฐ์๋ ์ด๋ป๊ฒ ํด์ผํ๋?- ๋๊ฐ์ ๋ฆฌ์คํธ ์ ๋น๊ต๋ฅผ ์์ํ ๋ ํ๋๊ฐ ๋น์ด์์๊ฒฝ์ฐ์๋ ์ด๋ป๊ฒ ํ๋?
ํด๊ฒฐ
- Recursion ๋ฐฉ๋ฒ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐ ํ๋ค.
- ๋ฆฌ์คํธ ๋์ค ํ๋๊ฐ ๋น์ด์๋ค๋ฉด ๋ค๋ฅธ ๋ฆฌ์คํธ ๋ฐํ
- ๋๊ฐ์ ๋ฆฌ์คํธ์
val
๊ฐ์ ๋น๊ต ํ์ฌmergeTwoLists(_:, _:)
๋ฅผ ํธ์ถ
- ๋ฉ์๋ ํธ์ถ ์์
- ๋ฉ์๋ Call Stack ์์๋๋ก ๋ฐํ๋์ด ์ง๋ ๊ฐ
- xcode Call stack when list1 = 1,2,4, list2 = 1,3,4
๊ฒฐ๊ณผ
func mergeTwoLists(_ list1: ListNode?, _ list2: ListNode?) -> ListNode? {
//๋ฆฌ์คํธ ๋์ค์ ํ๋๊ฐ ๋น์ด ์์๊ฒฝ์ฐ
guard let list1 = list1 else {
return list2
}
guard let list2 = list2 else {
return list1
}
//๋ฆฌ์คํธ์ next ๊ฐ์ด nil ์ด ๋ ๋๊น์ง ์งํ
if list1.val < list2.val {
list1.next = mergeTwoLists(list1.next, list2)
return list1
} else {
list2.next = mergeTwoLists(list1, list2.next)
return list2
}
}
Time complexity = O(n+m)
where n, m refers to length of each list
Space complexity = O(1)
5.0 Palindrome Linked List
๊ณ ๋ฏผ
- ๋ณดํต ๋ฐฐ์ด์ด๋ String ์ Palindrome(ํ๋ฌธ) ์ฌ๋ถ๋ reverse ๋ฅผ ์ฌ์ฉํด์ ์๋ ์๋ ๊ฐ๊ณผ ๋น๊ตํ๋ ์์ผ๋ก ๊ตฌํํด์๋ค. ํ์ง๋ง ๋ฌธ์ ์์ O(1) ์ Space Complexity ๋ฅผ ์๊ตฌํ๊ธฐ์ ๊ณ ๋ฏผ๋๋ ๋ถ๋ถ์ด ๋ง์๋ค.
- reverse ๋ง๊ณ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์์๊น?
- reverse ๋ฅผ ์ด๋ป๊ฒ ํ๋ฉด extra memory ๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด์ ๊ตฌํ ํ ์ ์์๊น?
ํด๊ฒฐ
-
reverse ๋ง๊ณ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์์๊น? (with Space complexity O(1))
- list ์ ๊ฐ์๋ฅผ ์ผ๋ค์ ๋ง์ง๋ง headNode.next ๊ฐ์ head ์ ์ฒซ๋ฒ์งธ node ๋ก ์ฐ๊ฒฐ์ํจ๋ค. ๊ทธํ ์นด์ดํธ๋ ๋ฆฌ์คํธ ๊ฐ์๋งํผ ๋ฌดํํ ์ฐ๊ฒฐ๋ list ๋ฅผ ์ํํ๋ฉด์ ์์๊ฐ ๊ฐ์์ง ์ฒดํฌํ๋ค.
-> [1,2,4], [1,2,2,1] ๊ฐ์ ์ผ์ด์ค๋ ํต๊ณผํ์ง๋ง [1,1,2,1] ๊ฐ์ ๊ฒฝ์ฐ ์ฑ๋ฆฝํ์ง ๋ชปํ๋ค. (๋ฆฌ์คํธ๋ฅผ ์ฐ๊ฒฐํ๋ค๊ณ ํด๋ ๋ฆฌ์คํธ์ ์ญ์์ ๊ตฌํํ ์์์๊ธฐ ๋๋ฌธ์ด๋ค).
-> ์คํจ
-
reverse ๋ฅผ ์ด๋ป๊ฒ ํ๋ฉด extra memory ๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด์ ๊ตฌํ ํ ์ ์์๊น?
-
์ฒซ๋ฒ์งธ ์๋๋ ๋ฆฌ์คํธ ์ ์ฒด๋ฅผ ๊ทธ๋ฅ reverse ํด๋ดค์ง๋ง ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ next ๊ฐ์ด ๋ฐ๋๋ฉด์ ์ฐธ์กฐ๋ head ์ list ์ ์ํฅ์ ๋ผ์ณ ๋ฒ๋ ธ๋ค.
-
๋๋ฒ์งธ ์๋๋ ๋ฆฌ์คํธ ์ค๊ฐ ๊น์ง์ ํฌ์ธํธ๋ฅผ ์ฐพ์์
์ค๊ฐ์ง์ ์ ๋ ธ๋
๋ฅผreverse
ํ๋ค์ ์๋ headNode ์ ๊ฐ๋ค๊ณผ ๋น๊ต๋ฅผ ํ๋ ๊ฒ์ด๋ค.- ์ค๊ฐ์ง์ ์ ์ฐพ๋๋ฐ ์ฌ๋ฌ๊ฐ์ง ์๊ฐํด์ผํ ์ ๋ค์ด ์์๋ค.
- case 1: ๋ฆฌ์คํธ๊ฐ ๋น์ด์์๊ฒฝ์ฐ
- case 2: ๋ฆฌ์คํธ๊ฐ ํ์์ธ๊ฒฝ์ฐ
curr
,inspector
two ํฌ์ธํฐ ๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์๋ค.inspector
๋ ๊ฐ iteration ๋ง๋ค๋ค์ ๋ ธ๋
์2๋ฒ์งธ ๋ค์ ๋ ธ๋
๊ฐ nil ์ธ์ง ํ์ธํ๋ค. ๊ทธ๋ฆฌ๊ณ nil ์ด ์๋๋ผ๋ฉดinspector
๋ 2๊ฐ์ ๋ ธ๋๋ค ๋ฅผ ํฌ์ธํ ํ๊ฒ ๋๊ณ ,curr
์ ๋ค์ ๋ ธ๋๋ฅผ ๊ฐ๋ฅดํค๊ฒ ๋๋ค.๋ง์ฝ ๋ฆฌ์คํธ ๋ ธ๋์ ๊ฐ์๊ฐ ํ์ (3๊ฐ ~> [1,2,3]) ์ธ๊ฒฝ์ฐ์
curr.next
์ธ [3] ๋ ธ๋๋ฅผ ๋ฐํํ๊ฒ ๋๋ค.[3] ์ reverse ํด๋ reversedList ์ ๋ค์ ์์๊ฐ nil ์ผ๋๊น์ง๋ง original head ์ ์์์ ๊ฐ์ ๋น๊ตํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ input ์ด [1,2,1] ์ผ ๊ฒฝ์ฐ์๋ ์ด ์๊ณ ๋ฆฌ์ฆ์ ์ ํจํ๊ฒ ๋๋ค.
-
๊ฒฐ๊ณผ
func isPalindrome(_ head: ListNode?) -> Bool {
let midNode = getLastHalfList(head: head)
var reversedMidNode = reverseList(midNode)
var curr = head
while reversedMidNode != nil {
if curr?.val != reversedMidNode?.val {
return false
}
reversedMidNode = reversedMidNode?.next
curr = curr?.next
}
return true
}
//pass firsthalf of list
func getLastHalfList(head: ListNode?) -> ListNode? {
var curr = head
var inspector = head
while inspector?.next != nil && inspector?.next?.next != nil {
inspector = inspector?.next?.next
curr = curr?.next
}
return curr?.next
}
func reverseList(_ head: ListNode?) -> ListNode? {
//revseredList ๋ ์ด๊ธฐ๋ก Nill ์ ์ฃผ์ ๊ฐ์ ๊ฐ์ง๊ณ ์์.
var revseredList: ListNode? = nil
//curr ์ head ์ ์ฒซ๋ฒ์จฐ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํค๊ณ ์์.
var curr = head
//nextNode ๋ head ์ ๋ค์ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํด.
var nextNode = curr?.next
while curr != nil {
//curr ์ ๋ค์ ์์์ ์ฃผ์ ๊ฐ์ temp ๋ก ์ง์
curr?.next = revseredList
revseredList = curr
curr = nextNode
nextNode = curr?.next
}
return revseredList
}
Time Complexity = O(n)
Space Complexity = O(1)
5.0 Linked List Cycle
๊ณ ๋ฏผ
- ์ด๋ป๊ฒ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ฅผ ์ฒดํฌ ํด์ค์ ์์๊น?
- node ๋ค์ ์ด๋ป๊ฒ ๋น๊ตํด์ ๊ฐ์ ๋ ธ๋์ธ์ง ํ์ธํ ์ ์์๊น?
- ํจํด์ผ๋ก ํ์ธํด์ผํ๋?
- ์ฃผ์ด์ง ์ ์ฝ์ฌํญ์ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํ์ด๋ณผ๊น?
ํด๊ฒฐ
-
์ด๋ป๊ฒ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ฅผ ์ฒดํฌ ํด์ค์ ์์๊น?
-> ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ฅผ ์ฒดํฌํ๋ ค๋ฉด extra memory ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฅํด์ผํ๋๋ฐ, space complexity O(1) ์ ์ ์ฝ์ฌํญ์ ๋ชป ์งํค๊ฒ๋๋ค.
-
ํจํด์ผ๋ก ํ์ธํด์ผํ๋?
-> ์ด๊ฒ๋ํ extra memory ํ์
-
์ฃผ์ด์ง ์ ์ฝ์ฌํญ์ ์ด์ฉํด๋ณผ๊น?
-> ์ ์ฝ์ฌํญ์ ๋ฆฌ์คํธ์ ๊ธธ์ด๊ฐ
[0, 1e4]
์๋ค. ๋ฐ๋ผ์ while loop ์์ ๋ ธ๋์ ๊ฐ์๋ฅผ ์ธ์ด 1e4 ์ด์์ผ๋ก ๊ฐ์๊ฐ ์ธ์ด์ง๋ค๋ฉด true ๋ฅผ ๋ฐํํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ง๋ดค์ง๋ง... ์คํจ๋ ๋ค๋ฆ์ด ์์๋ค.. -
node ๋ค์ ์ด๋ป๊ฒ ๋น๊ตํด์ ๊ฐ์ ๋ ธ๋์ธ์ง ํ์ธํ ์ ์์๊น?
- Node ๊ฐ Equatable ์ด ์๋๊ณ , unique ํ id ๋ ์์ด์ ์ด๋ป๊ฒ ๊ฐ์ ๋
ธ๋์ธ์ง ํ์ธํ ๊น ๊ณ ๋ฏผ์ ํ๋์ค
===
์ฐ์ฐ์ ๋ฅผ ์๊ฒ๋์๋ค. ===
๋ObjectIdentifier
๋ฅผ ์ฌ์ฉํ์ฌ ๋น๊ต๋๋ ๋์๋ค์ด ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ฃผ์๋ฅผ ์ฐธ์กฐํ๊ณ ์๋์ง ํ์ธํด์ค๋ค.- ๊ฐ์ ๋
ธ๋์ธ์ง ํ์ธํ ๋ฐฉ๋ฒ์ด ์๊ฒผ์ผ๋, ์๋ ์์์ ๊ฐ์ด ๋ง์ฝ ์ํ๋๊ณ ์๋ ์์๋ผ๋ฉด two pointer ์ ์ฌ์ฉํด์ ์๋์ ๊ฐ์ด ์ํ๋๊ณ ์๋ ๋ฆฌ์คํธ์ธ์ง ํ์ธํ ์์๋ค.
- curr pointer ๋ ๋ฆฌ์คํธ์ ๋ ธ๋๋ฅผ ์ฐจ๋ก๋๋ก ์ง์ ๋ก ๊ฑด๋๋ฐ๋ inspector ์ ๋ ธ๋์ ๋น๊ต๋ฅผ ํ๊ฒ๋๋ค. (inspector ๋ ๋ฆฌ์คํธ๊ฐ์์ ์ ์ฝ์ ๋ฐ๋ผ ๋ช๊ฐ๋ฅผ ๊ฑด๋๋ด ๋ ธ๋๋ฅผ ๊ฒ์ฌํ ๊ฑด์ง ์ ํด์ค์์๋ค)
- Node ๊ฐ Equatable ์ด ์๋๊ณ , unique ํ id ๋ ์์ด์ ์ด๋ป๊ฒ ๊ฐ์ ๋
ธ๋์ธ์ง ํ์ธํ ๊น ๊ณ ๋ฏผ์ ํ๋์ค
๊ฒฐ๊ณผ
func hasCycle(_ head: ListNode?) -> Bool {
var curr = head
var inspector = head?.next
while inspector != nil {
if curr === inspector {
return true
}
curr = curr?.next
inspector = inspector?.next?.next
}
return false
}
Time Complexity = O(n)
where n = original length of list
Space Complexity = O(1)
1.0 Maximum Depth of Binary Tree
๊ณ ๋ฏผ
TreeNode
์right
,left
์ค ๋๋ค nil ์ด ์๋์์ ์ด๋ค ๋ฐฉํฅ์ผ๋ก search ํด์ผํ๋?
ํด๊ฒฐ
- Recursive ํจ์๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํจ.
BaseCondition
=right
,left
๋ ธ๋๊ฐ ๋๋ค Nil ์ผ์ ํ์ฌcount
๋ฅผ ๋ฐํ.- ๋ฐ๋ณตํด์ ํจ์๋ฅผ ๋ถ๋ฅผ๋๋,
right
,left
์ ๋ ธ๋์ ๊น์ด๊ฐ ๊น์๊ฒ์ ์ฌ์ฉํ์ฌcount
์ ๋ํด์ ๋ฐํํด์ค๋ค.
๊ฒฐ๊ณผ
func maxDepth(_ root: TreeNode?) -> Int {
// guard var root = root else {return 0}
let curr = root
let leftNode = root?.left
let rightNode = root?.right
var cnt = curr == nil ? 0 : 1
//Base case
if leftNode == nil && rightNode == nil {
return cnt
} else {
cnt += max(maxDepth(leftNode), maxDepth(rightNode))
return cnt
}
}
Time Complexity = O(n)
Space Complexity = O(1)
2.0 Validate Binary Search Tree
๊ณ ๋ฏผ
- parent TreeNode ๋ฐ๋ก ๋ฐ์ ์๋ subtree ์์ BST validation ์ ์ฝ๊ฒ ๊ตฌํํ์ง๋ง, tree ๊ฐ ๊น์ด์ง๊ณ ์ธต์ด ์๊ธฐ๋ฉด์ ์์์ ์๋ tree node ์ ํ์์ ์๋ node ์ BST validation ์ ์งํํ๋ ๋ถ๋ถ์์ ์ด๋ ค์์ ๋ง์ด ๊ฒช์๋ค.
ํด๊ฒฐ
-
1.0 ์์ ๋ ธ๋์ ๊ฐ๊ณผ ๋น๊ตํ์ฌ ํ์ฌ ๋ ธ๋๊ฐ ์ ํจํ BST ์ธ์ง ํ์ธํด์ฃผ๊ธฐ ์ํ์ฌ
low
,high
integer ํ์ ์ ๋ฒ์๋ฅผ ํ ๋นํ๋ค. -
2.0
validateRange(TreeNode, Low, High)
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ subtree node ์ ๋ฐฉํฅ์ ๋ฐ๋ฅธ BST validation Range ๊ฐ์ ์ง์ ํ ์ ์๋๋ก ํด์ฃผ์๋ค. -
3.0 ๋ฐ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ํธ๋ฆฌ์ ์ค๋ฅธ์ชฝ ๋ ธ๋์ subtree ๊ฐ nil ์ด ๋ ๋๊น์ง ํจ์๋ฅผ recursive ํ๊ฒ ํธ์ถํ๊ฒ๋๋ค. (์ค๋ฅธ์ชฝ subtree ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๋ง์น๋ค, ์ผ์ชฝ subtree ๋ฅผ ์งํํด์ฃผ๋๋ก ๊ตฌํํ๋ค.)
initial value
- low & high = 0
BaseCase
- ํ์ฌ ๋
ธ๋๊ฐ nil ์ผ๊ฒฝ์ฐ
true
๋ฐํ. (subtree ๊ฐ ์์์ ์ ์ํ BST ์) - BST Range ๊ฐ์ ํ์ฌ ๋
ธ๋์ ๊ฐ์ด ๋ฒ์ด๋ ๊ฒฝ์ฐ
false
๋ฅผ ๋ฐํ
Recursive
- ์ค๋ฅธ์ชฝ subtree ๊ฒ์ฌ๋ค, ์ผ์ชฝ subtree ๊ฒ์ฌ์งํ
๊ฒฐ๊ณผ
func isValidBST(_ root: TreeNode?) -> Bool {
return validateRange(root, high: nil, low: nil)
}
func validateRange(_ root: TreeNode?, high: Int?, low: Int?) -> Bool {
print("Inspecting : \(root?.val), low = \(low), high = \(high)")
guard let curr = root else {return true}
// The current node's value must be between low and high.
if let low = low, curr.val <= low {
return false
} else if let high = high, curr.val >= high {
return false
}
return validateRange(curr.right, high: high , low: curr.val) && validateRange(curr.left, high: curr.val, low: low)
}
Time Complexity = O(n)
Space Complexity = O(n)
3.0 Symmetric Tree
๊ณ ๋ฏผ
- O(1) ์ Space Complexity ๋ก ๋ฌธ์ ๋ฅผ ํ์ ์์๊น ๊ณ ๋ฏผํจ.
ํด๊ฒฐ
-
Recursive ํ๊ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ์ํด ์ง๊ด์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํด์ผํ ์ง ์๊ฐํด๋ดค๋ค.
-
1.0 ์ฃผ์ด์ง root ์ left, right ๊ฐ์ ๊ฐ์์ผํ๋ค. (์๋์ false)
-
2.0
left.left == right.right && left.right == right.left
๊ฐ ์ฑ๋ฆฝํด์ผ symmetric ํ ๊ฒ์ ์์์๋ค. -
์ ์ ์ฌ๋ก ์๋์ ๊ฐ์ด recursive ํจ์๋ฅผ ์ค๊ณํ ์ ์์๋ค.
Basecase
1.0 ์์ ํฌ์ธํธ์์ ๋ ๋ ธ๋์ ๊ฐ์ด nil ์ด๋ผ๋ฉด true ๋ฐํ (๋น๊ตํ ๊ฒ์ด ์๊ธฐ๋๋ฌธ์ symmetic ํจ)
2.0 ์์ ํฌ์ธํธ์์ ๋๋ ธ๋์ ๊ฐ์ด ๊ฐ์ง ์๋ค๋ฉด false ๋ฐํ
3.0 ๋ ๋ ธ๋์ subtnode ๊ฐ์ด ๊ฐ์ง ์๋ค๋ฉด false ๋ฐํ
Recursive
left.left == right.right && left.right == right.left
๋ฅผ ๋น๊ตํด์ฃผ๊ธฐ ์ํ์ฌ ๋๊ฐ์ nodeTree ๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ๋ validateValue(left: TreeNode?, right: TreeNode?) -> Bool
๋ฅผ ์์ฑํ์ฌ ๋ฐ๋ณต๋ถ์ ์คํ.
ํด๊ฒฐ
func isSymmetric(_ root: TreeNode?) -> Bool {
//initial states
return validateValue(left: root?.left, right: root?.right)
}
func validateValue(left: TreeNode?, right: TreeNode?) -> Bool {
print("A = \(left?.val), B = \(right?.val)")
//Basecase1 : ์์ ํฌ์ธํธ์์ ๋๋
ธ๋์ ๊ฐ์ด nil ์ด๋ผ๋ฉด true ๋ฐํ (๋น๊ตํ ๊ฒ์ด ์๊ธฐ๋๋ฌธ์ symmetic ํจ)
if (left?.val == nil && right?.val == nil) {return true}
//Basecase2 : ์์ ํฌ์ธํธ์์ ๋๋
ธ๋์ ๊ฐ์ด ๊ฐ์ง ์๋ค๋ฉด false ๋ฐํ
if (left?.val != right?.val) {return false}
//Basecase3 : ๋ ๋
ธ๋์ subtnode ๊ฐ์ด ๊ฐ์ง ์๋ค๋ฉด false ๋ฐํ
print("A.left = \(left?.left?.val), B.right = \(right?.right?.val)")
print("A.right = \(left?.right?.val), B.left = \(right?.left?.val)")
if (left?.left?.val != right?.right?.val) && (left?.right?.val) != (right?.left?.val) {
return false
}
//Recursive
return validateValue(left: left?.left, right: right?.right) && validateValue(left: left?.right, right: right?.left)
}
Time Complexity = O(n)
Space Complexity = O(1)
4.0 Binary Tree Level Order Traversal
๊ณ ๋ฏผ
- ์ด๋ป๊ฒ ๋ค์ level ๋ก ๋์ด๊ฐ์ผํ๋์ง ์์ ์๋์ง์ ๋ํด์ ๊ณ ๋ฏผ์ ํ๋ค.
ํด๊ฒฐ
-
์ฒ์์ ํธ๋ฆฌ์ subtree ๊ฐฏ์๋ฅผ ์นด์ดํ ํ๋ ๋ก์ง์ ๊ตฌ์ํ์ฌ ๋ค์ level ๋ก ๋์ด๊ฐ์ง ์ ํด์ค๊น ์๊ฐํ๋๋ฐ, ์ฝ๋๊ฐ ๋๋ฌด ๋ณต์กํด์ ธ์ ๋ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
-
Queue
๋ฅผ ์ฌ์ฉํ์ฌ์ ์ฒซ๋ฒ์งธ ๋ ธ๋๋ถํฐ ์ฐจ๋ก๋๋ก Enqueue ๋ฅผ ํ๋ค์ ์ด์ค while ๋ฌธ์ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.- 1.0 Queue ๊ฐ
empty
๋ ๋๊น์ง outer loop ์ ๋๋ฆฐ๋ค. - 2.0 ๋ ๋ฒจ์ ํ์ํ๊ธฐ์ํด ํ์ฌ queue ์ ๋
ธ๋๊ฐ์๋ฅผ
cnt
์ ์ ์ฅํ๋ค. (ํ์ฌ level ์ ๋ ธ๋ ๊ฐ์) - 3.0 innerLoop ์์ ์ฒซ๋ฒ์งธ ๋
ธ๋๋ฅผ ์ ์ฐ๊ฒฐ๋์ด ์๋
subNode(left,right)
๋ฅผ queue ์ enqueue ํด์ฃผ๋ฉฐ ๋ค์ level ์ ๋ ธ๋ ๊ฐ์๋ฅผ ์ ๋ฐ์ดํธ ํด์ค๋ค. ์ด๋ ์ ์ฅ๋cnt
๋ฅผ -1 ํด์ฃผ๋ฉฐ 0 ์ด ๋ ๋๊น์ง ์งํํ๋ค. (์ฌ๊ธฐ์cnt
๋ ํ์ฌ level ์ ์๋ node ์ ๊ฐ์๋ฅผ ์๋ฏธํ๋ค.)
๊ฒฐ๊ณผ
- 1.0 Queue ๊ฐ
func levelOrder(_ root: TreeNode?) -> [[Int]] {
var res: [[Int]] = []
var queue: [TreeNode?] = []
guard let curr = root else {return res}
queue.append(curr)
while (!queue.isEmpty) {
var level: [Int] = []
var count = queue.count - 1
while (count >= 0) {
if let node = queue.removeFirst() {
level.append(node.val)
count -= 1
//enqueue next Nodes
if let left = node.left {queue.append(left)}
if let right = node.right {queue.append(right)}
}
}
res.append(level)
}
return res
}
Time Complexity = O(n)
Space Complexity = O(n)
5.0 Convert Sorted Array to Binary Search Tree
๊ณ ๋ฏผ
- ์ผ์ชฝ / ์ค๋ฅธ์ชฝ subtree ๋ฅผ ์ด๋ค์์ผ๋ก ์ฃผ์ด์ง ๋ฐฐ์ด์ ๊ธฐ๋ฐ์ผ๋ก ํ์ฑํด์ผํ ์ง ๊ณ ๋ฏผ.
ํด๊ฒฐ
-
์๋ 1: Non recursive method
-
์ผ์ชฝ / ์ค๋ฅธ์ชฝ subtree ๋ฅผ ์ด๋ค์์ผ๋ก ์ฃผ์ด์ง ๋ฐฐ์ด์ ๊ธฐ๋ฐ์ผ๋ก ํ์ฑํด์ผํ ์ง์ ๋ํ ๊ณ ๋ฏผ ์ ํด๊ฒฐํ๊ธฐ์ํด ์ฃผ์ด์ง ๋ฐฐ์ด์ ๊ฐ์ / 2, (์ค์ ์์) ๋ฅผ ๊ธฐ์ ์ผ๋ก ์ผ์ชฝ/์ค๋ฅธ์ชฝ subtree ๋ฅผ ๊ตฌ์ฑํ๋ ค๊ณ ํ๋ค.
-
๊ณผ์ :
- 1.0 ์ผ์ชฝ subTree ๋ฅผ ์ฃผ์ด์ง ๋ฐฐ์ด์ ๊ฐ์ด๋ฐ ์์์ ๊น์ง ๋ง๋ค์ด์ค๋ค. (์ผ์ชฝ, ์ค๋ฅธ์ชฝ subNode ๋ฅผ ๊ฑฐ๊พธ๋ก ์ฑ์ฐ๋ฉฐ)
- 2.0 ์ต์์ ๋ ธ๋๋ฅผ ์์ฑ๋ subtree ์์ ์ง์ ํด์ฃผ๊ณ , right subTree ์ ์์์ ์ ๋ง๋ค์ด์ฃผ๊ธฐ์ํด ๋ฐฐ์ด์์ ์์๋ฅผ ํ๋ ๋๋นผ์ right ์ ์ง์ ํด์ค๋ค.
- 3.0 ์ค๋ฅธ์ชฝ SubTree ๋ ๋จ์ ๋ฐฐ์ด์ด empty ๊ฐ ๋ ๋๊น์ง ๋ฐฐ์ด์ ๋ง์ง๋ง ์์๋ถํฐ ๋นผ์ right subtree ๋ฅผ ๊ตฌ์ฑํด์ค๋ค. (๋ฐฐ์ด์ ์ค๋ฆ์ฐจ์์ด๊ธฐ ๋๋ฌธ์ ์ค๋ฅธ์ชฝ subtree ์์๋ค์ ๊ตฌ์ฑํด์ค๋ ๋ง์ง๋ง ์์๋ถํฐ ๋นผ์ฃผ์๋ค.)
-
๋ง๋ฅํธ๋ฆฐ ๋ฌธ์ :
- 1.0,3.0 ์์์์ ์ ์๊ฐ์์ ๋ฐฐ์ด์ด ์ฃผ์ด์ง๊ฒฝ์ฐ์๋ queue ๋ฅผ ์ฌ์ฉํ์ง ์์๋ ํ๋์ ์ค๊ธฐ๋ก Node ๊ฐ ์ด์ด์ง๊ธฐ๋๋ฌธ์ ๋์์ง๋ง, ๋ฐฐ์ด์ด ๊ธธ์ด์ง๋ฉด ๋ช๋ฒ์งธ node ์ left right ๋ ธ๋๋ฅผ ๋ง๋ค์ด์ค๊ฒ์ธ์ง ์์๋ฅผ ์ ํด์ผํ๊ธฐ ๋๋ฌธ์ queue ๋ ์ฌ์ฉํด์ผํ๊ณ ์ฝ๋๊ฐ ๋๋ฌด ๊ธธ์ด์ง๋ค.
- 2.0 ์์์์ ๋ฐฐ์ด์ ์์๊ฐ ๋จ์ ์๋์ง ํญ์ ์ฒดํฌ๋ฅผ ํด์ฃผ์ด์ผํ๊ธฐ ๋๋ฌธ์ ์ฝ๋์ ์กฐ๊ฑด๋ฌธ์ด ๋๋ฌด ๋ง์ด ์๊ธด๋ค.
-
-
์๋ 2: Recursive method
๊ฒฐ๊ณผ
func sortedArrayToBST(nums: [Int]) -> TreeNode? {
guard !nums.isEmpty else { return nil }
let mid = nums.count / 2
let treeNode = TreeNode(nums[mid])
treeNode.left = sortedArrayToBST(nums: Array(nums[0..<mid]))
treeNode.right = sortedArrayToBST(nums: Array(nums[mid + 1..<nums.count]))
return treeNode
}
Time Complexity = O(n)
Space Complexity = O(n)
1.0 Merge Sorted Array
๊ณ ๋ฏผ
- ๋ ๋ฐฐ์ด์ ์์ํ๋ํ๋๋ฅผ ๋น๊ตํด์ ๋ง์ฝ
nums2
์ ์์๊ฐ์ด ๋ ์๋ค๋ฉด,nums1
์ ์ด๋ป๊ฒ ์ ๋ฐ์ดํธ ํด์ค์ผํ ์ง ๊ณ ๋ฏผ์ ๋ง์ด ํ๋ค.
ํด๊ฒฐ
- Two pointer ๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
pointer1
๋nums1
๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ฅผ ์ฒดํฌํด์ฃผ๊ณ ,pointer2
๋nums2
์ ์ธ๋ฑ์ค๋ฅผ ์ฒดํฌํ๋๋ก ๊ตฌ์ฑํ๋ค.While
๋ฌธ์ ์ฌ์ฉํ๋๋ฐpointer1
๊ฐ์ดvar pointer1Range = m
๋ณด๋ค ์๊ณ ,pointer2
๊ฐ์ดn
๊ฐ๋ณด๋ค ์์์ ๊ณ์ ๋ฐ๋ณตํ๋ผ๋ ์กฐ๊ฑด์ ์ฃผ์๋ค.nums2
์ ์์๊ฐ์ด ๋ ์๋ค๋ฉด,pointer1
์ธ๋ฑ์ค์nums2[pointer2]
๊ฐ์insert
ํด์ฃผ์ด ์ค๋ฆ์์๋๋ก ๋ฐฐ์น๊ฐ ๋๋๋ก ํด์ฃผ์๊ณ , ๋์์ ๋ค์ ์์๋ฅผ ๊ฐ๋ฅด์ผ ๋น๊ตํ ์ ์๋๋กpointer2
์ ๊ฐ์ +1, nums1 ์ ๋ฐฐ์ด์ insert ๋์์ผ๋ ์๋pointer1Range
๋ +1 ์ ํด์ฃผ์ด ๊ธฐ์กด์num1
์ ์๋ ์์๋ฅผpointer1
์ด ๋ค ๊ฐ๋ฅดํฌ์ ์๋๋ก ์ฒ๋ฆฌํด์ฃผ์๋ค.- ์ด๋ฐ์์ผ๋ก ์ฒ๋ฆฌ๋ฅผ ํด์ค๊ฒฝ์ฐ ๋ง์ฝ
nums1
์ ์ต๋๊ฐ์ดnums2
์ ์ต๋๊ฐ๋ณด๋ค ํ์ฐธ ๋ชป๋ฏธ์น ๊ฒฝ์ฐ ์๋์ ๊ฐ์ดnums2
์ ๋ชจ๋ ์์๊ฐ ๋น๊ต๋์ง ์๊ณ while ๋ฌธ์ด ๋๋ ๋ฒ๋ฆฌ๋ ์ํฉ์ด ๋๋ค.
nums2
์ ๋จ์ ๊ฐ๋ค ์ ์ฒ๋ฆฌ ํด์ฃผ๊ณinsert
๋ก ๋น๊ต๋ ๊ฐ๋ค์ ์ฒ๋ฆฌํด์ฃผ์๊ธฐ ๋๋ฌธ์ ๋จ์0
์ ๋ฐ๋ก ์ฒ๋ฆฌํด์ฃผ์ด์ผํ๋ ์ํฉ์ด ์ผ์ด๋ ๋ฒ๋ ธ๋ค.nums2
์ ๋จ์ ๊ฐ๋ค ์ ์ฒ๋ฆฌ ํด์ฃผ๊ธฐ: ๋ฐฐ์ด์replaceSubrange(_ range: Range<Int> ,with: newElements)
๋ฅผ ์๋์ ๊ฐ์ด ์ฌ์ฉํด์ผ ํ๋ค.- ๋ํ ์ด๋ฌํ ๊ฒฝ์ฐ๋ ์ค์ง
pointer2
๊ฐn
๊น์ง ๋๋ฌํ์ง ๋ชปํ์ ๊ฒฝ์ฐ์๋ง ์ฒ๋ฆฌํด์ฃผ์ด์ผํ๊ธฐ ๋๋ฌธ์ while๋ฌธ ์ดํ์ ์กฐ๊ฑด๋ฌธ์ ๋ฐ๋ก ์ฃผ์ด์ผํ๋ค.- ex) nums1 = [1], nums2 = [] ์ผ ๊ฒฝ์ฐ, nums1 ์ด [] ์ผ๋ก ํ ๋น๋๋ ์ํฉ์ด ์ผ์ด๋จ
- ๋จ์
0
์ ๋ฐ๋ก ์ฒ๋ฆฌ: ๊ธฐ์กด์ ์ฃผ์ด์ก๋ ๋ฐฐ์ด ๊ฐ๊ฐ์ ๊ธธ์ดm+n
์ ์ฌ์ฉํด์ 0์ด ํฌํจ๋nums1
์ ์ ๋ฐ์ดํธ ํด์ฃผ์ด์ผํ๋ค.
๊ฒฐ๊ณผ
func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) {
var pointer1 = 0
var pointer2 = 0
var pointer1Range = m
while (pointer1 < pointer1Range) && (pointer2 < n) {
if nums1[pointer1] > nums2[pointer2] {
nums1.insert(nums2[pointer2], at: pointer1)
pointer2 += 1
pointer1Range += 1
} else {
pointer1 += 1
}
}
if pointer2 != n {
nums1.replaceSubrange(pointer1..<nums1.count, with: Array(nums2[pointer2..<nums2.count]))
}
nums1 = Array(nums1[0..<m+n])
}
Time Complexity = O(n+m)
Space Complexity = O(n)
Three Pointer ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์ ํด๊ฒฐ๋ฐฉ๋ฒ (๋ฌด์กฐ๊ฑด Two Pointer ๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ํ์๋๋ฐ, ์ ๊ทธ๋ฌ๋์ง ๋ชจ๋ฅด๊ฒ ๋ค...)
- nums1 ์ ๋ง์ง๋ง ์ธ๋ฑ์ค๋ถํฐ nums1, nums2 ์ ๋ง์ง๋ง ์์๋ฅผ ๋น๊ตํ์ฌ ํฐ๊ฐ์ ๋จผ์ nums1 ์ ๋ง์ง๋ง์ ํ ๋น์์ผ์ฃผ๋ ๋ฐฉ์.
func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) {
var updatingPointer = m-m-1
var nums1Pointer = m-1
var nums2Pointer = n-1
while updatingPointer >= 0, nums2Pointer >= 0 {
if nums1Pointer >= 0, nums1[nums1Pointer] > nums2[nums2Pointer] {
nums1[updatingPointer] = nums1[nums1Pointer]
nums1Pointer -= 1
}else {
nums1[updatingPointer] = nums2[nums2Pointer]
nums2Pointer -= 1
}
updatingPointer -= 1
}
}
2.0 First Bad Version
๊ณ ๋ฏผ
- ๋ฌธ์ ๋ฅผ ์ดํดํ๋๋ฐ ์ด๋ ค์์ ๊ฒช์๋ค. input ์ด 5์, 4 ์ผ๋, 1...5 ๊น์ง์ integer ๋ฅผ ์ํํ๋ฉฐ ์ฒซ๋ฒ์งธ๋ก
isBad(n) = true, (4 in this ex)
์ธ ์ซ์๋ฅผ ๋ฆฌํดํ๋ ๋ฌธ์ ์๋ค. - ์ด๋ค์์ผ๋ก ์ํํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผํ๋์ง ๊ณ ๋ฏผํ๋ค.
ํด๊ฒฐ
-
์ฒซ๋ฒ์งธ ํด๊ฒฐ๋ฒ์ผ๋ก๋ ์์ํ๊ฐํ๊ฐ๋ฅผ ๊ฒ์ฌํ์ฌ ์ฒ์์ผ๋ก
True
๊ฐ ๋์ค๋ ๊ฐ์ ๋ฆฌํดํด์ฃผ์๋ค. (ํ์ง๋ง ์ซ์๊ฐ ์ปค์ง๊ธฐ ์์ํ๋ฉด์ time limit ์ ๊ฑธ๋ฆฌ๊ณ ๋ง๋ค) -
๋๋ฒ์จฐ ํด๊ฒฐ ๋ฐฉ์์ผ๋ก๋ ์ด์งํ์์ ๊ฒ์ํ์ฌ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๋ ค๊ณ ํ์ผ๋, recursion ์ ์ฌ์ฉํด์ ์ ๊ทผํ๋ ค๋ bad version ๋ ์ฒดํฌํด์ฃผ๋๊ณผ์ ๊ณผ, ์ด์ง ๊ฒ์ range ๋ ์ค์ ํด ์ฃผ๋๊ณผ์ ์์ ๋จธ๋ฆฌ๊ฐ ๋ฉ์ถฐ๋ฒ๋ฆฌ๊ณ ๋ง์๋ค.
-
๊ฒฐ๊ตญ ๋ต์ ๋ณด๊ณ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ฐ, ๊ต์ฅํ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก ๋ฌธ์ ๋ฅผ ์๋์ ๊ฐ์ด ํด๊ฒฐํ ์ ์์๋ค.
-
Left, Right, Mid pointer ๋ฅผ ์ฌ์ฉํ๋๋ฐ
isBad(Mid)
์ ๊ฐ์ด True, ์ผ๋์ False ์ผ๋ Range(left, right) ๋ฅผ ์ฌ์ค์ ํด์ฃผ์ด left ๊ฐ right pointer ๋ณด๋ค -1 ์ ์๋๊น์ง while ๋ฌธ์ ๋๋ฆฐ๋ค. -
#Scenario 1: mid pointer ์ ์์๊ฐ ๋ถ๋์ธ ๋ฒ์ ์ด ์๋๋
-
์ฃผ์ด์ง n = 6 ์ผ๋, [1,2,3,4,5,6] ์์๋ฅผ ๊ฒ์ฌํ๊ฒ๋๋๋ฐ
isBad(Mid) = false
์ผ๋ ์๊ฐํด๋ณด์
-
1 ์์ ์ค๊ฐ์ง์ ๊น์ง ๋ถ๋์ด ์๋ค๋ ๋ป์
์ค๊ฐ์ง์ ์ + 1 ์์
๋ถํฐ ๋ถ๋์ธ์ง ์ฒดํฌ๋ฅผ ํด์ฃผ์ด์ผํ๋ค๋ ๋ง์ด๋๋ค. ๋ฐ๋ผ์ ์ด์งํ์ ์ Range ๋ฅผ [mid+1, right] ๋ก ์ ๋ฐ์ดํธ ํด์ค๋ค. -
#Scenario 1: mid pointer ์ ์์๊ฐ ๋ถ๋์ธ ๋ฒ์ ์ผ๋
-
์ฃผ์ด์ง n = 6 ์ผ๋, [1,2,3,4,5,6] ์์๋ฅผ ๊ฒ์ฌํ๊ฒ๋๋๋ฐ
isBad(Mid) = True
์ผ๋ ์๊ฐํด๋ณด์
- ์ค๊ฐ ์ง์ ์์ ๋ถ๋์ด ๋์๋ค๋๋ป์ ๊ทธ ์ด์ ์ ๋์์์๋์๋ค๋ ๋ป์ด๋๋ค. ๋ฐ๋ผ์ ์๋ก์ด ์ด์งํ์ ์ range ๋ฅผ [left, mid] ๋ก ์ค์ ํด์ค๋ค. (๋ถ๋ ๋ฒ์ ์ธ mid ๋ฅผ ํฌํจํ๊ฒ ๋๋๋ฐ, ์ด๋ left pointer ๊ฐ +1 ์ฉ ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ์ผ๋ก ํ์๋ฒ์๋ฅผ ์ขํ์ค๊ธฐ๋๋ฌธ์ ๋ง์ง๋ง์ผ๋ก left pointer ๊ฐ right pointer ๋ฅผ ๊ฐ๋ฅดํค๊ฒ๋๋ฉด์ ๋ถ๋๋ฒ์ ์ ์ฐพ์๋ผ์์๊ฒ๋๋ค)
๊ฒฐ๊ณผ
func firstBadVersion(_ n: Int) -> Int {
var left = 1
var right = n
while left < right {
var mid = left + (right - left)/2 // n ๊ฐ ์ด์ปค์ง๋ฉด (right+left)/2 ๋ overflow ๋๊ธฐ๋๋ฌธ์, (right-left)/2 ๋ก ์ค๊ฐ์ง์ ์ ์ธ๋ฑ์ค ๊ณ์ฐ๋ค, ๊ธฐ์ค์ left ์ ๋ํด์ฃผ๋๋ก ๊ณ์ฐํ๋ค.
if isBadVersion(mid) {
var right = mid
}else {
var left = mid + 1
}
}
return left
}
Time Complexity = O(logn)
Space Complexity = O(1)
- DP ๋
ํฐ ๋ฌธ์
๋ฅผ๋ถ๋ถ ๋ฌธ์
๋ก ๋๋๊ณ ,๋ถ๋ถ๋ฌธ์
์ ์ ๋ต์ผ๋กํฐ ๋ฌธ์
์ ํด๋ต์ ์ฐพ์๊ฐ๋ ์๊ณ ๋ฆฌ์ฆ ์ค๊ณ๋ฒ ์ด๋ค. - ์ด๋ ๊ฒ ๋ณด๋ฉด
๋ถํ ์ ๋ณต
๋ฌธ์ ์ ๋น์ทํ๋ค๊ณ ๋๋ผ๊ฒ ์ง๋ง, ํด๋ฅผ ๊ตฌํ๊ธฐ ์ํด ์ชผ๊ฐ๋ถ๋ถ๋ฌธ์
์ ํน์ฑ์ด ๋ค๋ฅด๋ค. - ๋ถํ ์ ๋ณต๊ณผ ๋น๊ตํ์ ๋ ๋์ ํ๋ก๊ทธ๋๋ฐ์ ๋๋๋ผ์ง๋ ํน์ฑ์ ์๊ฒ ์ชผ๊ฐ์ง
๋ถ๋ถ ๋ฌธ์
๊ฐ ์ค๋ณต๋ผ์ ๋ํ๋๋ค๋ ๊ฒ์ด๋ค. - ๋ถํ ์ ๋ณต์ ํฐ ๋ฌธ์ ๊ฐ
์ ๋ํฌํ ๋ถ๋ถ ๋ฌธ์
๋ก ๋๋์ง๋ง๋์ ํ๋ก๊ทธ๋๋ฐ
์๋ถ๋ถ ๋ฌธ์
๊ฐ ๋ฐ๋ณต์ ์ผ๋ก ๋ฑ์ฅํ๋ค. ํฐ ๋ฌธ์
์ ํด๋๋ถ๋ถ ๋ฌธ์
์ ์กฐํฉ์ผ๋ก ์ฐพ์ ์ ์์ผ๋ฉฐ๋ฌธ์ ์ ํด๋ ๋์ผํ ์ฐ์ฐ์ผ๋ก ์ํ
๋์ด์ผ ํ๋ค.- ์ฐธ์กฐ
1.0 Climbing Stairs
๊ณ ๋ฏผ
- ์ด๋ค ๋ฐ๋ณต์ ์ธ ๋ถ๋ถ๋ฌธ์ ๊ฐ ์๋์ง ํ์ ํ๊ธฐ
- ์ด๋ค
๋ถ๋ถ ๋ฌธ์
์ ์กฐํฉ์ ์ฌ์ฉํด์ผํ๋?
ํด๊ฒฐ
- ์ด๋ค ๋ฐ๋ณต์ ์ธ ๋ถ๋ถ๋ฌธ์ ๊ฐ ์๋์ง ํ์
ํ๊ธฐ & ์ด๋ค ์กฐํฉ์ผ๋ก ์ด๋ฃจ์ด์ ธ์๋?
- ๊ณ๋จ์ ์ค๋ฅผ๋ 1,ํน์ 2 ์นธ์ฉ ์ค๋ฅผ์ ์๋ค๊ณ ์ฃผ์ด์ก๊ณ ,
n
๋ฒ์งธ ๊ณ๋จ์ ์ฌ๋ผ ์ ์๊น์ง ๋๋ฌํ๋ ๋ฐฉ๋ฒ์ ์๋ฅผ ๊ตฌํ๋ ๊ฒ์ด์๋ค. - 2๊ฐ์ ๊ณ๋จ์ ์ค๋ฅด๋ ๋ฐฉ๋ฒ์ 1์นธ์ฉx2 ์ 2์นธ์ ๋์์ ์ค๋ฅด๋๋ฒ: 2๊ฐ์ง์ด๋ค.
- 3๊ฐ์ ๊ณ๋จ์ ์ค๋ฅด๋ ๋ฐฉ๋ฒ์ 1๋ฒ์งธ ๊ณ๋จ์์๋ถํฐ 2์นธ์ ์ค๋ฅด๋๋ฐฉ๋ฒ, 2๋ฒ์งธ ๊ณ๋จ์์ 1์นธ์ ์ค๋ฅด๋ ๋ฐฉ๋ฒ: 3๊ฐ์ง์ด๋ค.
- 4๊ฐ์ ๊ณ๋จ์ ์ค๋ฅด๋ ๋ฐฉ๋ฒ์ (2๋ฒ์งธ๊ณ๋จ๊น์ง ์ค๋ฅด๋ ๋ฐฉ๋ฒ + 2์นธ์ ํ๋ฒ์ ๊ฐ๋๋ฒ), (3๋ฒ์งธ ๊ณ๋จ๊น์ง ์ค๋ฅด๋ ๋ฐฉ๋ฒ + 1์นธ์ ํ๋ฒ์ ๊ฐ๋๋ฒ) : 5๊ฐ์ง ์ด๋ค.
n๋ฒ์งธ
๊ณ๋จ์ ์ค๋ฅด๋ ๋ฐฉ๋ฒ์(An-2) + (An-1)
๊ฐ์ง ์ด๋ค.
- ๊ณ๋จ์ ์ค๋ฅผ๋ 1,ํน์ 2 ์นธ์ฉ ์ค๋ฅผ์ ์๋ค๊ณ ์ฃผ์ด์ก๊ณ ,
- ์ ์ ํ์์
ํผ๋ณด๋์น ์์ด
๊ณผ ๊ฐ๋ค.
๊ฒฐ๊ณผ
์๋ 1 (TimeLimit Exceeds)
๋ฌธ์ ์ ํด๋ ๋์ผํ ์ฐ์ฐ์ผ๋ก ์ํ
๋๊ธฐ๋๋ฌธ์ ์๋์ ๊ฐ์ด Recursive ํ๊ฒ ๋ฌธ์ ๋ฅผ ํ๋ฉด ์ค๋ณต๋ ๊ณ์ฐ์ ๊ณ์ ๋ฐ๋ณตํ๊ธฐ ๋๋ฌธ์ ์๊ฐ์ด ์ค๋๊ฑธ๋ฆฐ๋ค.
func climbStairs(_ n: Int) -> Int {
if n == 1 {return 1}
if n == 2 {return 2}
return climbStairs(n-1) + climbStairs(n-2)
}
์๋ 2 (Memoization)
- ์ค๋ณต๋ ๊ณ์ฐ์ ํผํ๊ณ ์ ์ด์ ์ ๊ตฌํ "๋ถ๋ฌธ ๋ฌธ์ "์ ํด๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด๋๋ ๋ฐฉ๋ฒ์ผ๋ก ํ์ด๋ดค๋ค.
func climbStairs(_ n: Int) -> Int {
var steps: [Int] = [0,1,2]
if n > 2 {
for i in 3...n{
steps.append(steps[i-1] + steps[i-2])
}
}
return steps[n]
}
Time Complexity = O(n)
Space Complextiy = O(n)
2.0 Best Time to Buy and Sell Stock
๊ณ ๋ฏผ
- ๋ฐฐ์ด์ ๊ฐ์ ๊ทธ๋ํ๋ก ๊ทธ๋ ค๋ณด๋ฉด peak ๊ฐ ์๊ธฐ๊ณ valley ๊ฐ ์๊ธฐ๋๋ฐ, valley ์์ peak ์ผ๋ก ์ฌ๋ผ๊ฐ๋ ๊ฐ์ด profit ์ด ๋๋ค๋ ์๊ฐ์ ํ๋ค.
- ๋ฐฐ์ด์ ์ํํ๋ฉด์ valley ์์ peak ์ผ๋ก ์ฌ๋ผ๊ฐ๋ ๊ฐ์ค ๊ฐ์ฅ ํฐ์๋ฅผ ๋ฆฌํด ํ๋ฉด ๋ ๊ฒ์ด๋ผ๋ ์๊ฐ์ ํ์ง๋ง, [4,2,7,3,9] ์ธ๊ฒฝ์ฐ [2,7] = 5, [3,9] = 6 ์ด์ง๋ง, [2,9] = 7 ์ ์กฐํฉ๋ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ๋ฒ์ผ๋ก ๋ฌธ์ ๋ฅผ ํ์ด์ผํ๋ค.
dp
๋ฌธ์ ๋ก ์ด๋ป๊ฒ ์ ๊ทผํด์ผํ๋์ง ๋ง์ด ๊ณ ๋ฏผํ์ง๋ง ๋์ ํ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ๋ ์ค๋ฅด์ง ์์ ๋ต์ ๋ณด๊ณ ๋ฌธ์ ๋ฅผ ํ์๋ค.
ํด๊ฒฐ
- DP ๋ ์์ ๋ฌธ์ ์ ๋ต์ ๊ตฌํ์ฌ ํฐ ๋ฌธ์ ๋ฅผ ํธ๋ ๋ฐฉ๋ฒ์ธ๋ฐ ์๋์๊ฐ์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
- ๋ฐฐ์ด์ ์ํ ํด๊ฐ๋ฉด์ ์ด์ ๋ ๋ณด๋ค ์์ ๊ฐ์
currentStock
์ ์ ์ฅํ๋ค. - ๋ฐฐ์ด์ ์ํ ํ๋ฉฐ ํ์ฌ ์คํก๊ฐ๊ณผ ์ ์ฅ๋
currentStock
์ ๋นผ์ฃผ์ด๋ง์ฝ ์ค๋ ์คํก์ ํ๋ค๋ฉด ์ผ๋ง์ profit ์ด ์๊ธฐ๋์ง = profitInspector
์ ์ ์ฅํ๋ค. maxiumProfit
์ด๋ผ๋ ๊ฐ์ 0 ์ผ๋ก ์ด๊ธฐํํ๋ค, ๋ง์ฝprofitInspector
๋ณด๋ค ๊ฐ์ด ์๋ค๋ฉดmaxiumProfit
์ ํ์ฌ์ profitInspector ์ผ๋ก ์ ๋ฐ์ดํธ ํด์ค๋ค.- ์ด DP ๋ฌธ์ ๋ ํ๋ฃจํ๋ฃจ ์คํก์ ํ์์ ๊ฒฝ์ฐ์ ๊ฐ์ ๊ณ์ฐํ์ฌ ํ์ฌ
maxiumProfit
๊ณผ ๋น๊ตํ์ฌ ์ ๋ฐ์ดํธ ํด์ฃผ๋ ์์ ๋ฌธ์ ์ ๋ต์ ํด๊ฒฐํด์๊ฐ์ฅ ๋์ profit
์ ๊ตฌํ๋ ๊ตฌํ๋ ๋ฌธ์ ์๋ค.
๊ฒฐ๊ณผ
func maxProfit(_ prices: [Int]) -> Int {
var currentStock = Int.max
var maxProfit = 0
var profitInspector = 0
for i in 0..<prices.count {
if prices[i] < currentStock {
currentStock = prices[i]
}
profitInspector = prices[i] - currentStock
if maxProfit < profitInspector {
maxProfit = profitInspector
}
}
return maxProfit
}
Time complexity = O(n)
Space complexity = O(1)
3.0 Maximum Subarray
๊ณ ๋ฏผ
- ์ด๋ค
Subproblem
์ผ๋ก ๋๋์์์๊น? O(n)
์์ ํ๊ธฐ
ํด๊ฒฐ
- ์ด๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์๊ฐ์ ํ๋ฆ์ "์ด๋ค
Subproblem
์ผ๋ก ๋๋์์์๊น?" ์์ ๋ถํฐ ์์๋์๋ค. - 1.0 ํ์ฌ ๋ด๊ฐ ๊ฐ์ง๊ณ ์๋
SubArray
์ ํฉ์ด ๋ค์ subarray ์ ํฉ๋ณด๋ค ์์์ง ํ์ธํ๋ค๋ณด๋ฉด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ง์์๊น? - 2.0
SubArray
์ ํฌ๊ธฐ๋0~nums.count
์ด๋ค. - 3.0 ์ด๋ป๊ฒ ๊ฐ์๋ฅผ ์ง์ ํด์ค์ ์์๊น?
- ์ด๋ป๊ฒ optimal ํ ๊ฐ์์ธ์ง ์์์๊ณ , ๊ทธ position ์ ์ด๋ป๊ฒ ์๊น?
-> ์ฒ์ 1๊ฐ์ ๊ทธ ๋ค์์๋ฅผ ๋น๊ตํด์ ๋ค์์๊ฐ ๋ํด๋ position ์ ๊ทธ ๋ค์ ์์๋ก ์ฎ๊ธฐ๋ฉด๋์ง ์์๊น?
-> ์ฒ์ 1๊ฐ๊ฐ ์๋๋ผ, ์์์ด๋๋ SubArray
๋ถํฐ์ Sum
์ ๊ทธ ๋ค์์์๋ ๋น๊ตํ๋ฉด ๋์ง ์์๊น?
-> ๋ง์ฝ ๊ทธ ๋ค์ ์์๊ฐ ์ด์ ์ sum
๋ณด๋ค ํฌ๋ฉด ์๋ก์ด ๊ธฐ์ค์ด๋๊ณ , ๊ทธ ๊ธฐ์ค๋ถํฐ Sum
์ ๊ตฌํ๋ฉด๋์ง ์์๊น?
-> ๋ฌธ์ ์ ์ ๋ชฉ์ ๋ง์น SubArray ๋ฅผ ์ฐพ๋ ๊ฒ ๊ฐ์๋ฐ, ํจ์๋ Sum: Int
์ ๋ฐํํ๊ณ ์๋ค. ๊ทธ๋ผ Sum
์ ์ ์ฅํด ๋์๋ค๊ฐ ์ฃผ์ด์ง ๋ฐฐ์ด์์ ๋์ฌ์ ์๋ ์ต๋ ์๋ฅผ ๊ตฌํ๋ฉด๋์ง ์๋?
-
๋ฌธ์ ๋ ์๋์ ๊ฐ์ด 2๊ฐ์ง์ ํฐ ๋ฌธ์ ๋ก ๋๋๋ค.
-
Scenario 1 :
ฮฃ nums[StartingPointer...Counter]
>nums[Counter+1]
StartPointer
๋ ์ด๋ค์์๋ถํฐ ๋ํด์ค๊ฒ์ธ์ง์ ๋ํ ๊ธฐ์ค์ ์ด ๋๋ค. ๋ฐ๋ผ์Counter
๊ฐ ์ฆ๊ฐํ ๋๋ง๋คStartPointer
๊ฐ ๊ฐ์์ฮฃ nums[StartingPointer...Counter]
๊ฐ๊ณผnums[Counter+1]
์ ๋น๊ตํ์ฌnums[Counter+1]
๊ฐ ์ด์ Sum ๋ณด๋ค ์์์, ๋ํด์ฃผ์ดmaxSum
๊ณผ ๊ฐ์ ๋น๊ตํ๋ค. ์ด๋maxSum
๋ณด๋ค ๊ฐ์ด ํฌ๋ฉดmaxSum
์ ์ ๋ฐ์ดํธ ํด์ฃผ๊ฒ ๋๋ค.
- Scenario 2 :
ฮฃ nums[StartingPointer...Counter]
<nums[Counter+1]
- ์ด์ ์ Sum ์ด ๋ค์ ์์๋ณด๋ค
์๋ค๋ฉด
, ๋ค์ ๊ฐ์ ์๋ก์ด ๊ธฐ์ค์ผ๋ก ํด์ค์ผํ ์ง ์๊ฐํด๋ด์ผํ๋ค. - ๋ง์ผ,
์ด์ ์ ํฉ๊ณผ ๋ค์์์์ ํฉ
>๋ค์์์์ ๊ฐ
์ผ๋, ๊ธฐ์ค(StartPointer)์ ์ ๋ฐ์ดํธ ํด์คํ์๊ฐ ์๊ฒ๋๋ค. - ๋ง์ง๋ง์ผ๋ก
์ด์ ์ ํฉ๊ณผ ๋ค์์์์ ํฉ
๊ณผ ํ์ฌ ๊ธฐ๋ก๋์ด์๋maxSum
์ ๋น๊ตํด์ ์ ๋ฐ์ดํธ ํด์ฃผ๋ฉด ๋๋ค.
- ์ด์ ์ Sum ์ด ๋ค์ ์์๋ณด๋ค
- ์ฒ์์
์ด์ ์ ์์๋ค์ ํฉ
์ ๊ตฌํ ๋reduce
๊ณ ์ฐจํจ์๋ฅผ ์ฌ์ฉํ์ผ๋,O(n^2)
์๊ฐ ๋ณต์ก๋ ๊ฐ ํ์ฑ๋์ด ํจ์ค๋ฅผ ํ์ง ๋ชปํ๋ค. - ๋ฐ๋ผ์
curr
์ด๋ ๋ณ์๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ ๊ณ์ ๋ํด์ฃผ๋์์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
func maxSubArray(_ nums: [Int]) -> Int {
var cnt = 0
var startPointer = 0
var maxSum = nums[cnt]
var curr = nums[cnt]
while cnt < nums.count-1 {
//๋ง์ฝ ๋ค์๊ฐ์ด ๋ํฌ๋ค๋ฉด sp ์
๋ฐ์ดํธ
if curr < (nums[cnt+1]) {
startPointer = cnt+1
curr = max(curr+nums[startPointer],nums[startPointer])
} else {
curr += nums[cnt+1]
}
if curr > maxSum {
maxSum = curr
}
cnt += 1
}
return maxSum
}
-
Time complexity:
O(n)
-
Space complexity:
O(1)
4.0 House Robber
๊ณ ๋ฏผ
- ์ด๋ฌธ์ ๋ ๋์ ํ ํ์๊ฐ ์์ด์ ์ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํด์ ๋ฌธ์ ๋ฅผ ํ์๋ค.
ํด๊ฒฐ
- ์์ฒญ๋๊ฒ ๊ณ ๋ฏผํ๋๋ฐ ์๊ฐ๋ณด๋ค ๊ฐ๋จํ ์๋์ ๊ฐ์ด ํ์ ์์๋ค.
- rob1 = 0 , rob2 = 0 ์ด๋ผ๋ ์ด๊ธฐ๊ฐ์ ํ ๋นํ๋ค.
- ๋ฐฐ์ด์ ์ํํ๋ฉฐ,
max(์๋ก์ด ์์+rob1, rob2)
๊ฐ์ ์ฐพ์๋ด์ด ๋ง์ฝ์๋ก์ด ์์+rob1
(์๋กญ๊ฒ ํฐ๋ ์ง) ์ด ์ด์ ๊ฐrob2
๋ณด๋ค ํฌ๋ค๋ฉดtemp
๊ฐ์ ์ ๋ฐ์ดํธ ํด์ค๋ค. - rob1 ๊ณผ rob2 ์ ๊ฐ์ ๋ฐ๊พผ๋ค.
- ์ด๋ฅผ ๋ง์ง๋ง ์์๊น์ง ๋ฐ๋ณต.
- ์ต์ข ์ ์ผ๋ก rob2 ์ ๊ฐ์ฅ ๋ง์ด ํ์น ์ ์๋์์ ๊ฐ์ด ์ ์ฅ๋๋ค.
๊ฒฐ๊ณผ
func rob(_ nums:[Int]) -> Int{
var rob1 = 0
var rob2 = 0
for num in nums {
var temp = max(rob1 + num, rob2)
rob1 = rob2
rob2 = temp
}
return rob2
}
Time Complexity = O(n)
Space Complexity = O(1)
1.0 Shuffle an Array
๊ณ ๋ฏผ
shuffle
์ ์ด๋ป๊ฒ ๊ตฌํํ ๊น
ํด๊ฒฐ
Stride
๋ฅผ ์ฌ์ฉํด ์๋์ ๊ฐ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐ
๊ฒฐ๊ณผ
func shuffled(_ nums:[Int] ) -> [Int] {
var copy = nums
for i in stride(from: nums.count-1, through: 1, by: -1){
let index = Int.random(in: 0...i)
if index != i {
copy.swapAt(i, index)
}
}
return copy
}
Time Complexity = O(n)
Space Complexity = O(1)
2.0 Min Stack
๊ณ ๋ฏผ
- ์ด๋ป๊ฒ
minium
๊ฐ์ ์ ์งํ ์ ์์๊น?
ํด๊ฒฐ
[(element,min)]
์ ์ด์ฉํ์ฌ ํ์ฌpush
๋ ๋์ Minimum ๊ฐ์ ๊ฐ์ด ์ ์ฅํ๋ค.
๊ฒฐ๊ณผ
class MinStack {
private var stack: [(element:Int, min:Int)] = []
init() {}
func push(_ val: Int) {
if stack.isEmpty {
stack.append((val,val)) //์ฒซ๋ฒ์งธ min์ val ๊ฐ๋จ.
}else{
stack.append((val,min(val,getMin())))
}
}
func pop() {
_ = stack.popLast()
}
func top() -> Int {
return stack.last!.element
}
func getMin() -> Int {
return stack.last!.min
}
}
Time Complexity = O(n)
Space Complexity = O(1)
1.0 FizzBuzz
๊ณ ๋ฏผ
- 3,5 ์ ๊ณต๋ฐฐ์์, ๊ฐ๊ฐ์ ๋ฐฐ์์ผ ๋ ๋ง๋ค์ด์ผํ๋ String ์กฐํฉ์ด ๋ค๋ฅธ๊ฒ์ ์ด๋ค๋ฐฉ๋ฒ์ผ๋ก ํํํด์ค๊น?
ํด๊ฒฐ
%
mod operator ๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ํด๊ฒฐEnum associated type
์ ์ฌ์ฉํด์ ํฉํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ
๊ฒฐ๊ณผ
enum FizzBuzz {
case compute (Int)
var string:String {
switch self {
case .compute(let num):
if num % 3 == 0 && num % 5 == 0 {
return "FizzBuzz"
}else if num % 5 == 0 {
return "Buzz"
}else if num % 3 == 0 {
return "Fizz"
}else{
return "\(num)"
}
}
}
}
func fizzBuzz(_ n: Int) -> [String] {
var res: [String] = []
for i in 1...n {
let fizzbuzz: FizzBuzz = .compute(i)
res.append(fizzbuzz.string)
}
return res
}
Time Complexity = O(n)
Space Complexity = O(n)
2.0 Count primes
๊ณ ๋ฏผ
- ์์ ํ๋ณ๋ฒ
- ์๋ผํ ์คํ ๋ค์ค์ ์ฒด ๊ตฌํํ๊ธฐ
ํด๊ฒฐ
- ์์์ ํ๋ณ์ 2,3,5,7 ์ ์๋ก ๋๋์ด ๋จ์ด์ง์ง ์๋ ์ ์ด๋ค.
- ์๋ผํ ์คํ
๋ค์ค์ ์ฒด ๋
2,3,5,7
์ ๋ฐฐ์ ๋ฅผ ์ ์ธํ ํ๋ฉด ํด๋น์๊น์ง์ ์์๊ฐ ๋ช๊ฐ ์๋์ง ์์ ์๋ค.
๊ฒฐ๊ณผ
func countPrimes(_ n: Int) -> Int {
var divisor = 2
var cnt = 0
var primes = Array(repeating: true, count: n)
if n < 2 {return cnt}
//Outer loop to go through 2,5,7,9..
while divisor * divisor < n {
if primes[divisor] == true {
var i = divisor
while i*divisor < n {
primes[i*divisor] = false
i += 1
}
}
divisor += 1
}
for i in 2..<n {
cnt += primes[i] == true ? 1 : 0
}
return cnt
}
Time Complexity = O(n)
(์๋ ์๋ผํ ์คํ
๋ค์ค์ ์ฒด ์๊ณ ๋ฆฌ์ฆ์ O(log(logn))
์ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ณ ์์.
Space Complexity = O(n)
3.0 Power of Three
Intuition
We can get the logarithms form with base of 3 by the following equation.
Then I would compute power of that exponent on base 3 to see if the that is equal to n
In short, log3(n) = log10(n)/log10(3), Check if n == 3^log3(n)
Code
class Solution {
func isPowerOfThree(_ n: Int) -> Bool {
if n <= 0 {return false}
var r = (log(Double(n))/log(3.0)).rounded()
return n == Int(pow(3, r))
}
}
Complexity
- Time complexity:
O(1)
- Space complexity:
O(1)
4.0 Romans to Integer
๊ณ ๋ฏผ
- ์ด๋ค ๋จ์๋ก ๋จ์ด๋ฅผ ๋์ด์ ๋ฌด์จ๊ฐ์ธ์ง ํํํด์ค๊น?
- ๋จ์ด๋ฅผ ๋์ด์ ํ๋ณํ๋ ๋ฐฉ๋ฒ์ธ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ์์๊น?
ํด๊ฒฐ
- ์๋ 1
- Given
s = MCMXCIV
- M, CM, MC, MC, XC, CI, IV ๋๋ก 2๊ฐ์ฉ ๋์ด์ ํด๋น ๋ฌธ์์ ๋ฑ๋ก๋ ๊ฐ์ด ์๋ค๋ฉด ์๋์ ๊ฐ์ด ์ฒ๋ฆฌ.
- C -> CM ์ด ์๋ค๋ฉด, C ์์ 100 ์ ๋ํด์ฃผ๊ณ , CM ์์ 900 - 100 ์ ํด์ค 800 ์ ๋ํด์ฃผ์ด 1000-100 ๊ณผ ๊ฐ์ ๊ฐ์ผ๋ก ์ฒ๋ฆฌ๋๋๋ก ๊ตฌํ.
- ์ด๋ Swift string ์ subscript ์ ์ฌ์ฉํ ๋
String.index
๋ฅผ ์ฌ์ฉํด์ผํ๊ธฐ ๋๋ฌธ์, ๋จ์ด ํ๋๋ฅผword
๋ผ๋ ๋ณ์์ ๋ํด์ฃผ๊ณ ํ์ฌ ๋์ ์ธ๋ฑ์ค์ ๋-1 ์ธ๋ฑ์ค๋ฅผ ๋ฐ๋ก ์์ฑํด์ค๋ค. - ๋ํ
enum
์ผ๋ก ๊ฐ case ๋ง๋ค ํ ๋น๋๋ ๊ฐ์ ์ง์ ํด์ค๋ค.
- Given
enum romans: String {
case I
case V
case X
case L
case C
case D
case M
case IV
case XL
case CD
case IX
case XC
case CM
var value: Int {
switch self {
case .I:
return 1
case .V:
return 5
case .X:
return 10
case .L:
return 50
case .C:
return 100
case .D:
return 500
case .M:
return 1000
case .IV:
return 3
case .XL:
return 30
case .CD:
return 300
case .IX:
return 8
case .XC:
return 80
case .CM:
return 800
}
return 0
}
}
func romanToInt(_ s: String) -> Int {
var word: String = ""
var res = 0
for string in s {
word += String(string)
if word.count > 1 {
let endIndex = word.index(before: word.endIndex)
let lastWordIndex = word.index(endIndex, offsetBy: -1)
let lastTwoWords = String(word[lastWordIndex...endIndex]) //Retrieve lastTwoWords
if let value = romans(rawValue: String(lastTwoWords))?.value {
res += value
continue
}
}
res += romans(rawValue: String(string))!.value
}
return res
}
- ์๋2 : ์๋จ์ด์ ๊ฐ์ ํ์ธํ์ฌ, ํ์ฌ ๊ฐ๋ณด๋ค ํด์ ๋นผ์ฃผ๋ฉด์ ๊ตฌํ
- Given
s = MCMXCIV
- ๋ง์ฝ i+1 ๋ฒ์งธ ๋จ์ด์ ๊ฐ์ด i ๋ฒ์งธ ๋จ์ด์ ๊ฐ๋ณด๋ค ํด์, ์ด๋ 1 < 5, 100 < 1000 ๋ฑ์ ์ผ์ด์ค๋ก ๋๋์ ์์.
- i ๋ฒ์งธ๋ ๊ฐ ์๋ฆฌ์๋ฅผ ๋ปํ๋๋ฐ, ๋ง์ฝ i+1 ๋ฒ์งธ ๋จ์ด์ ๊ฐ์ด ํฌ๋ค๋ฉด ํ์ฌ๊ฐ์ sum ๊ฐ์์ ๋นผ์ค๋ค์, i+1 ๊ฐ์ ๋ํด์ฃผ๋ฉฐ ์ฒ๋ฆฌํ๋ค.
- ์ด๋ฐฉ๋ฒ์ String.index ๋ฅผ ์์ฑํ ํ์๊ฐ ์์ผ๋ฉฐ, enum ์ case ๋ํ I, V, X, L, C, D, M ์ธ์ ๋ค๋ฅธ ๊ฐ์ ์ฒ๋ฆฌํด์ค ํ์๊ฐ ์์ด์ง๋ค.
- Given
enum romans2: String {
case I
case V
case X
case L
case C
case D
case M
var value: Int {
switch self {
case .I:
return 1
case .V:
return 5
case .X:
return 10
case .L:
return 50
case .C:
return 100
case .D:
return 500
case .M:
return 1000
}
}
}
func romanToInt(_ s: String) -> Int {
var res = 0
let arr = Array(s)
for i in 0..<arr.count {
let val = romans2(rawValue: String(arr[i]))!.value
if i+1 < arr.count, val < romans2(rawValue: String(arr[i+1]))!.value {
res -= val
}else {
res += val
}
}
return res
}
Complexity
- Time complexity:
O(n)
- Space complexity:
O(1)
1.0 Number of 1 Bits
๊ณ ๋ฏผ
- ์ฃผ์ด์ง input ์ ํํ๊ฐ binary ๋ก ์ฃผ์ด์ง๋๊ฑด๊ฐ?
- ๋ฌธ์ ๋ฅผ ์ฝ์์๋๋ binary ํํ๋ก ์ฃผ์ด์ง๋ ์ค์์๋๋ฐ, decimal ํํ์ Int ๊ฐ์ผ๋ก ๊ฐ์ด ๋ค์ด์ด.
ํด๊ฒฐ
- ์ฃผ์ด์ง decimal ๊ฐ์ binary ํํ๋ก ๋ฐ๊พธ๋ ๊ณผ์ ์ ๋๋จธ์ง ๊ฐ์ด 1์ผ๋ cnt+1 ์ ํด์ฃผ์ด ๋ฌธ์ ํด๊ฒฐ.
๊ฒฐ๊ณผ
func hammingWeight(_ n: Int) -> Int {
var cnt = 0
var val = n
while val > 0 {
if val % 2 == 1 {
cnt += 1
}
val = val / 2
}
return cnt
}
-
Time complexity:
O(n)
-
Space complexity:
O(1)
2.0 Hamming Distance
๊ณ ๋ฏผ
- bit-wise operator ๋ฅผ ์ฌ์ฉํ ์ง ๋ง์ง ๊ณ ๋ฏผ..
ํด๊ฒฐ
- bit-wise operator ๋ฅผ ์ฌ์ฉํ๋๊ฒ๊ณผ ์ํ๋๊ฒ์ ์ฐจ์ด๊ฐ ์์. (์๊ฐ๋ณต์ก๋, ๊ณต๊ฐ๋ณต์ก๋ wise)
- ์ฌ๋์ด ์๊ฐํ๋ decimal to binary ๋ฐฉ๋ฒ
n/2
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ. (shift operator ์ฌ์ฉ๊ฐ๋ฅ)
๊ฒฐ๊ณผ
func hammingDistance(_ x: Int, _ y: Int) -> Int {
var cnt = 0
var val1 = x
var val2 = y
while val1 != 0 || val2 != 0 {
if val1 % 2 != val2 % 2 {
cnt += 1
}
val1 = val1 / 2
val2 = val2 / 2
}
return cnt
}
-
Time complexity:
O(n)
-
Space complexity:
O(1)
3.0 Reverse Bits
๊ณ ๋ฏผ
- Bit-wise operator ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ ํ๊ธฐ
ํด๊ฒฐ
-
Bitwise Left and Right Shift Operators The bitwise left shift operator (<<) and bitwise right shift operator (>>) move all bits in a number to the left or the right by a certain number of places, according to the rules defined below.
-
Bitwise left and right shifts have the effect of multiplying or dividing an integer by a factor of two. Shifting an integerโs bits to the left by one position doubles its value, whereas shifting it to the right by one position halves its value.
-
32 bit unsigned integer ์ bit ์ ๋ค์ง์ด ๋ฒ๋ ค์ผํจ.
-
32bit ๋ง์ง๋ง ์ซ์๊ฐ 1 ์ธ์ง 0 ์ธ์ง ํ์ธ ํ๋ค์
-
1 ์ผ์์
res
๊ฐ์ +1 ํด์ค. -
res
๊ฐ์shift operator
๋ฅผ ์ฌ์ฉํ์ฌ ์ผ์ชฝ์ผ๋ก ํ์นธ์ฉ ์ด 32๋ฒ ์ฎ๊ฒจ์ผํจ. -
unsigned ๋๊น 31 bit ๊น์ง ์ 1์ผ์์ +1 ํด์ฃผ๋ ์กฐ๊ฑด๋ฌธ์ ์ ์ฉ์ํด
๊ฒฐ๊ณผ
func reverseBits(_ n: Int) -> Int {
var n = n
var result = 0
//์ฃผ์ด์ง ๊ฐ ๋ง์ง๋ง๋ถํฐ 1 ์ธ์ง 0์ธ์ง ํ์ธํ๊ณ , 1์ด๋ฉด result ์ 1bit ๋ฅผ ๋ง์ง๋ง ์๋ฆฌ์์ ์ถ๊ฐ ํด์ค.
//์ด ๊ณผ์ ์ n ์ด 0 ์ด ๋ ๋๊น์ง ์งํ.
for i in 0..<32 {
result += (n & 1) // (n ์ ๋ง์ง๋ง ์๋ฆฌ๊ฐ 0 ์ธ์ง 1 ์ธ์ง ์๊ธฐ ์ํด์ & operator ๋ฅผ ์ฌ์ฉ)
n >>= 1 // n ์ / 2 ํด์ค
if i < 31 { //31๋ฒ ํด์ฃผ๋๋ฐ.... unsigned ๋ผ ๊ทธ๋ฐ๋ฏ.
result <<= 1 // ์ค๋ฅธ์ชฝ shift ํด์ค (result ๊ฐ * 2).
}
}
return result
}
-
Time complexity:
O(1)
-
Space complexity:
O(1)
4.0 Pascal's Triangle
๊ณ ๋ฏผ
- Brute Force ๋ฐฉ๋ฒ ์ด์ธ์ ๊ตฌํํ ์ ์๋ ๋ฐฉ๋ฒ์ ์์๊น?
ํด๊ฒฐ
-
์๋1 : Brute Force
- 2์ค for loop ์ ๋๋ฉด์ ๋ ๋ฒจ ํ๋์ฉ ์ฑ์์ค
func generate(_ numRows: Int) -> [[Int]] { var res: [[Int]] = [] for row in 0..<numRows { var rows: [Int] = [] for i in 0...row { if i == 0 || i == row { rows.append(1) }else { rows.append(res[row-1][i-1] + res[row-1][i]) } } res.append(rows) } return res }
-
Time complexity:
O(n^2)
-
Space complexity:
O(n)
5.0 Valid Parentheses
๊ณ ๋ฏผ
- ์ด๋ป๊ฒ ์ง์ ๋ง์ถฐ์ผํ๋ ๊ณ ๋ฏผํ๋๋ฐ, ์์ ์์๋๋ก ํ๋ํ๋ ๊ฒ์ฌํ๋ ๋ฐฉ๋ฒ์ ์คํจํ๋ค.
- ํํธ๋ฅผ ์ฐพ์ ๋ดค๋๋ Stack ์ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฅผ ํ์์ ์์๊ฒ ๊ฐ์๋ค.
ํด๊ฒฐ
- ๋์ ๋๋ฆฌ ํํ๋ก ๋ซํ bracket ์ key, ์ด๋ฆฐ bracket ์ value ๋ก ํ ๋นํด๋ ผ๋ค.
- ์ฃผ์ด์ง
s
๋ฅผ ์ํํ๋ฉด์ ๋ง์ฝ ์์๊ฐ ๋ซํ ๊ฒ์ด๋ผ๋ฉด, ๊ทธ์ ๋ง๋ ์ด๋ฆฐ bracket ์ ๋์ ๋๋ฆฌ๋ฅผ ์ด์ฉํด์ ์ฐพ๋๋ค. - stack ์ ๋งจ์์ ์๋ ์์๋ฅผ ๋ถ๋ฌ์ ๋์ ๋๋ฆฌ์์ ์ฐพ์ ์ด๋ฆฐ bracket ๊ณผ ๊ฐ์ ์์์ธ์ง ํ์ธํ๋ค. (ํ๋ฆด์ false ๋ฐํ)
- ๋ง์ฝ ๋์
๋๋ฆฌ์ ๋ง์ง ์์ ์์๋ผ๋ฉด, ์ด๋ฆฐ ์์์ด๊ธฐ๋๋ฌธ์ stack ์
append
ํด์ค๋ค. - ๋ง์ง๋ง์ผ๋ก stack ์ด ๋น์ด ์์ง ์๋ค๋ฉด ์ง์ด ๋ง์ง ์๋
s
์ด๊ธฐ ๋๋ฌธ์ false ๋ฅผ ๋ฐํํด์ค๋ค.
๊ฒฐ๊ณผ
func isValidParentheses(_ s: String) -> Bool {
let brackets: [String:String] = [")":"(","]":"[","}":"{" ] //closed: open
var stack: [String] = []
for char in s {
if let matchedBracket = brackets[String(char)], let lastString = stack.popLast() {
if lastString != matchedBracket {
return false
}
continue
}
stack.append(String(char))
}
return stack.isEmpty
}
-
Time complexity:
O(n)
-
Space complexity:
O(n)
6.0 Missing Number
ํด๊ฒฐ
- (๋ฐฐ์ด ํฌ๊ธฐ + 1) = (0 ๋ถํฐ ์ต๋์ ๊น์ง์ ํฌ๊ธฐ) ์ ํฉ์ ์ฃผ์ด์ง ๋ฐฐ์ด์ ํฉ๊ณผ ๋นผ์ ๋๋จธ์ง ์๋ฅผ ๋ฐํ
func missingNumber(_ nums: [Int]) -> Int {
var sum = nums.reduce(0,+)
var expectedSum = Array(0...nums.count).reduce(0,+)
return expectedSum - sum
}
-
Time complexity:
O(n)
-
Space complexity:
O(1)