Skip to content

TaeKyeongKim/AlgorithmStudy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 

Repository files navigation

AlgorithmStudy

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


Array

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" ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ผ๊ณ  ํ•œ๋‹ค.

๊ณ ๋ฏผ: ์–ด๋–ป๊ฒŒ ์ค‘๋ณต๋œ์š”์†Œ๋ฅผ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ฑธ๋Ÿฌ๋‚ผ์ˆ˜์žˆ์„๊นŒ?

์‹œ๋„1

์ ‘๊ทผ ๋ฐฉ์‹: ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ ๋‹ค์Œ ์š”์†Œ๊ฐ’๊ณผ ๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด ๋‹ค์Œ์š”์†Œ์˜ ๊ฐ’์„์š”์†Œ๊ฐ’์˜ range ์™ธ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ด์ฃผ๊ณ  ๋งˆ์ง€๋ง‰์— filter ํ•ด์ค€๋‹ค.

๊ฒฐ๊ณผ: ์—ฐ์†ํ•ด์„œ 2๊ฐœ ์ด์ƒ์˜ ์š”์†Œ๊ฐ€ ๊ฐ™์€ ๊ฐ’์ด๋ฉด ์ค‘๋ณต๋œ๊ฐ’์„ ๋ฐ”๊พธ์–ด ์ค„์ˆ˜ ์—†์Œ -> ex) [1,1,1] -> [1,101,1]

์‹œ๋„2

์ ‘๊ทผ๋ฐฉ์‹

  • 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
}
image
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 ์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

image

๊ฒฐ๊ณผ: ์„ฑ๊ณต.

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

๋ฌธ์ œ๋งํฌ

๊ณ ๋ฏผ: ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์š”์†Œ๋ฅผ ์˜ฎ๊ธธ๋•Œ ์–ด๋–ป๊ฒŒ ๋‹ค์Œ ๊ฐ’์„ ์ €์žฅํ•ด์„œ ๊ทธ ๋‹ค์Œ ์ธ๋ฑ์Šค์— ๋Œ€์ž…ํ•ด์ค„์ˆ˜ ์žˆ์„๊นŒ?

์‹œ๋„1

์ ‘๊ทผ ๋ฐฉ์‹: 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)

์‹œ๋„2

์ ‘๊ทผ ๋ฐฉ์‹: 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)

์‹œ๋„3

์ ‘๊ทผ ๋ฐฉ์‹: 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

์‹œ๋„1

์ ‘๊ทผ๋ฐฉ์‹ : 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)

์‹œ๋„2

์ ‘๊ทผ๋ฐฉ์‹ : 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 ๋กœ ์ง€์ •ํ–ˆ๋‹ค.
image
  • 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 ์œผ๋กœ ์ค‘๋ณตํ™•์ธ์„ ์ง„ํ–‰ํ–ˆ๋‹ค.
  • 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 ์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ–ˆ์—ˆ๋‹ค.

      • ๊ธฐ์กด์— ์ƒ๊ฐํ–ˆ๋˜ ์ค‘๋ณตํ™•์ธ ๋ฐฉ๋ฒ•
    image

    -> ๋ฌธ์ œ : loop ์—์„œ i๋ฒˆ์จฐ row ์š”์†Œ ์ „์ฒด๋ฅผ ์ˆœํšŒ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— squareSet ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌํ•˜๋Š”๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅ.

    • row ์— ์žˆ๋Š” ๋ชจ๋“  ์š”์†Œ๋“ค์„ sqaureSet ์— ์ง‘์–ด ๋„ฃ๊ธฐ ์œ„ํ•ด์„  3๊ฐœ์˜ sqaureSet ์ด ํ•„์š”ํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ var squareSet = Array(repeating: Set<Character>(), count: (board.count/3)) ์™€ ๊ฐ™์ด squareSet ์„ ์ดˆ๊ธฐํ™” ํ•ด์ฃผ์—ˆ๊ณ  i๋ฒˆ์งธ row ๋ฅผ ์ˆœํšŒ ํ• ๋•Œ 3๊ฐœ์”ฉ ์š”์†Œ๋ฅผ ๋Š์–ด์„œ sqaureSet ์— ํ• ๋‹นํ•ด์ฃผ์—ˆ๋‹ค.
    image

    ๊ฒฐ๊ณผ

    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 ๋ฅผ ์ˆœํšŒ ํ•˜๋ฉด์„œ ๊ฐ๊ฐ์˜ ์š”์†Œ๋ฅผ ๊ฐ๋ณ€์— ๊ณ„์‚ฐ๋œ ์ขŒํ‘œ์— ๊ฐ’์„ ํ• ๋‹นํ•œ๋‹ค.

image

2.0 n*n ์˜ ๋ฐฐ์—ด์„ ์–ด๋–ป๊ฒŒ ์ˆœํšŒ ํ•ด์•ผํ• ์ง€ ๊ณ ๋ฏผ

  • ์ผ๋‹จ i ๋ฒˆ์งธ row ๋ฅผ ์ˆœํšŒ ํ•˜๊ณ , j ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์ˆœํšŒ ํ•  outter loop ๊ณผ inner loop ์ด ํ•„์š”ํ•˜๋‹ค.

  • outer loop: n ๊ฐœ์˜ row ๋ฅผ ์–ด๋–ป๊ฒŒ ์ˆœํšŒ ํ• ๊นŒ?

    • ํ•„์š”ํ•œ row ์˜ ๊ฐœ์ˆ˜๋Š” ๋ช‡๊ฐœ ์ธ๊ฐ€?
      • 4x4 ๋ฐฐ์—ด ์ผ๋•Œ๋ฅผ ๊ฐ€์ •ํ•ด๋ณด์ž
      • ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ 2๊ฐœ์˜ ์‚ฌ๊ฐํ˜•์œผ๋กœ ๋‚˜๋ˆŒ์ˆ˜๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  row ์˜ ์ •๋ณด๋งŒ์œผ๋กœ ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋Œ๋ฉด์„œ rotate ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
    image
    • 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 ์š”์†Œ์˜ ์ˆœํšŒ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ• ์ˆ˜์žˆ๋‹ค.
image

3.0 Element ํšŒ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ธ์šฐ๊ธฐ

  • 1.0 ์—์„œ ์ฐพ์€ ๋ฐฉ๋ฒ•์„ ์–ด๋–ค ๋กœ์ง์„ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•ด์•ผํ• ๊นŒ?
  • ์ผ๋‹จ ์ „์ฒด์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ๋ฆ„์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
  • ex) i = 0, j = 0
image
//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)


String

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 ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€ ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์•Œ๋งž์€ ์ž๋ฆฌ์ˆ˜์— ํ• ๋‹นํ• ์ˆ˜ ์žˆ์„๊นŒ?

ํ•ด๊ฒฐ

์‹œ๋„1

  • [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 ๋ฅผ ์‚ฌ์šฉํ•จ.

์‹œ๋„2

  • 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 ์ผ์น˜ํ•˜๋Š”์ง€ ์•Œ์ˆ˜ ์žˆ์„๊นŒ?

ํ•ด๊ฒฐ

์‹œ๋„1

  • Set ์„ ์ด์šฉํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ’€๋ ค๊ณ  ํ–ˆ์œผ๋‚˜, ์ค‘๋ณต๋œ character ์˜ ๊ฐœ์ˆ˜๋„ ์ผ์น˜ํ•ด์•ผํ•œ๋‹ค๋Š”๊ฒƒ์„ ๊นจ๋‹ซ๊ณ  ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ดค๋‹ค.

์‹œ๋„2

  • 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)


LinkedList

1.0 Delete Node in a Linked List

๊ณ ๋ฏผ

  • ์ฃผ์–ด์ง„ LikedList ์˜ ํŠน์ • node ๋ฅผ ์ง€์šฐ๋ฉด ๋˜๋Š”๋ฐ ํ•จ์ˆ˜์˜ input ์€ linkedList ๋ฐ–์— ์—†์–ด์„œ ๋‹นํ™ฉํ•จ

ํ•ด๊ฒฐ

  • LikedList ์™€ ํŠน์ • node ๊ฐ€ ์ฃผ์–ด์ง€๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์ด ํ•จ์ˆ˜๋ฅผ ๋ฐ–์—์„œ ์‚ฌ์šฉํ–ˆ์„๋•Œ ํ•จ์ˆ˜์—์„œ ์ฃผ์–ด์ง„ ๋…ธ๋“œ๋ฅผ ๋ฆฌ์ŠคํŠธ์—์„œ ์‚ญ์ œํ•˜๋ผ๋Š” ๋œป์ด์˜€๋‹ค.
  • ์ฃผ์–ด์ง„ ๋…ธ๋“œ์˜ ๊ฐ’์€ ๊ทธ ๋‹ค์Œ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ์ฃผ์–ด์ง„ ๋…ธ๋“œ์˜ nextNode ๋Š” node.next.next ๋ฅผ ๊ฐ€๋ฅดํ‚ค๊ณ  ์žˆ๋Š”๊ฒƒ์ด๋‹ค. image
 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 ์˜ ์—ฐ๊ฒฐ ์„ ๋Š๋Š”๋‹ค.
image

-> ์ œ์ผ ์ฒ˜์Œ ์š”์†Œ๋ฅผ ์‚ญ์ œํ•ด์•ผํ•˜๋Š” 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 ์„ ๊ฐ€๋ฅดํ‚ฌ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต.
  • ์ „์ฒด์ ์ธ ํฌ์ธํ„ฐ ์ง„ํ–‰ ๋ฐฉํ–ฅ ๋ฐ ์ฒ˜์Œ ํฌ์ธํ„ฐ๋“ค์ด ๊ฐ€๋ฅดํ‚ค๊ณ  ์žˆ๋Š” ๋…ธ๋“œ ์ฃผ์†Œ
image
  • ํฌ์ธํ„ฐ์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ์—…๋ฐ์ดํŠธ ๋ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ง„ํ–‰์ˆœ์„œ ๋„์‹ํ™”
image

๊ฒฐ๊ณผ

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(_:, _:) ๋ฅผ ํ˜ธ์ถœ
  • ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ˆœ์„œ
image
  • ๋ฉ”์„œ๋“œ Call Stack ์ˆœ์„œ๋Œ€๋กœ ๋ฐ˜ํ™˜๋˜์–ด ์ง€๋Š” ๊ฐ’
image
  • 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] ์ผ ๊ฒฝ์šฐ์—๋„ ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์œ ํšจํ•˜๊ฒŒ ๋œ๋‹ค.

image

๊ฒฐ๊ณผ

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 ๋Š” ๋ฆฌ์ŠคํŠธ๊ฐœ์ˆ˜์˜ ์ œ์•ฝ์— ๋”ฐ๋ผ ๋ช‡๊ฐœ๋ฅผ ๊ฑด๋„ˆ๋›ด ๋…ธ๋“œ๋ฅผ ๊ฒ€์‚ฌํ• ๊ฑด์ง€ ์ •ํ•ด์ค„์ˆ˜์žˆ๋‹ค)
    image

๊ฒฐ๊ณผ

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)


Trees

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 ๊ฒ€์‚ฌ์ง„ํ–‰
image

๊ฒฐ๊ณผ

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 ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ๋ฐ˜๋ณต๋ถ„์„ ์‹คํ–‰.

image

ํ•ด๊ฒฐ

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 ์˜ ๊ฐœ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค.)

    ๊ฒฐ๊ณผ

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

    • ๊ณผ์ •:
      • 1.0 ์ตœ์ƒ์˜ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์˜ ๊ฐ€์šด๋ฐ์š”์†Œ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.
      • 2.0 ์ตœ์ƒ์œ„ ๋…ธ๋“œ๋ฅผ ๊ธฐ์ ์œผ๋กœ left, right subtree ๋ฅผ ํ˜•์„ฑํ•ด์ค€๋‹ค. (recursive ํ•˜๊ฒŒ ์•„๋ž˜ ๊ทธ๋ฆผ ์ฐธ์กฐ) image

๊ฒฐ๊ณผ

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)


Sorting and Searching

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 ๋ฌธ์ด ๋๋‚˜ ๋ฒ„๋ฆฌ๋Š” ์ƒํ™ฉ์ด ๋‚œ๋‹ค.
image
  • nums2 ์˜ ๋‚จ์€ ๊ฐ’๋“ค ์„ ์ฒ˜๋ฆฌ ํ•ด์ฃผ๊ณ  insert ๋กœ ๋น„๊ต๋œ ๊ฐ’๋“ค์„ ์ฒ˜๋ฆฌํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚จ์€ 0 ์„ ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ์–ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์ผ์–ด๋‚˜ ๋ฒ„๋ ธ๋‹ค.
  • nums2 ์˜ ๋‚จ์€ ๊ฐ’๋“ค ์„ ์ฒ˜๋ฆฌ ํ•ด์ฃผ๊ธฐ: ๋ฐฐ์—ด์˜ replaceSubrange(_ range: Range<Int> ,with: newElements) ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ๋‹ค.
  • ๋˜ํ•œ ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋Š” ์˜ค์ง pointer2 ๊ฐ€ n ๊นŒ์ง€ ๋„๋‹ฌํ•˜์ง€ ๋ชปํ–ˆ์„ ๊ฒฝ์šฐ์—๋งŒ ์ฒ˜๋ฆฌํ•ด์ฃผ์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— while๋ฌธ ์ดํ›„์— ์กฐ๊ฑด๋ฌธ์„ ๋”ฐ๋กœ ์ฃผ์–ด์•ผํ–ˆ๋‹ค.
    • ex) nums1 = [1], nums2 = [] ์ผ ๊ฒฝ์šฐ, nums1 ์ด [] ์œผ๋กœ ํ• ๋‹น๋˜๋Š” ์ƒํ™ฉ์ด ์ผ์–ด๋‚จ
image
  • ๋‚จ์€ 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 ์˜ ๋งˆ์ง€๋ง‰์— ํ• ๋‹น์‹œ์ผœ์ฃผ๋Š” ๋ฐฉ์‹.
image
 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 ์ผ๋•Œ ์ƒ๊ฐํ•ด๋ณด์ž

image
  • 1 ์—์„œ ์ค‘๊ฐ„์ง€์ ๊นŒ์ง€ ๋ถˆ๋Ÿ‰์ด ์—†๋‹ค๋Š” ๋œป์€ ์ค‘๊ฐ„์ง€์ ์˜ + 1 ์š”์†Œ๋ถ€ํ„ฐ ๋ถˆ๋Ÿ‰์ธ์ง€ ์ฒดํฌ๋ฅผ ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค๋Š” ๋ง์ด๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ด์ง„ํƒ์ƒ‰ ์˜ Range ๋ฅผ [mid+1, right] ๋กœ ์—…๋ฐ์ดํŠธ ํ•ด์ค€๋‹ค.

  • #Scenario 1: mid pointer ์˜ ์š”์†Œ๊ฐ€ ๋ถˆ๋Ÿ‰์ธ ๋ฒ„์ „์ผ๋•Œ

  • ์ฃผ์–ด์ง„ n = 6 ์ผ๋•Œ, [1,2,3,4,5,6] ์š”์†Œ๋ฅผ ๊ฒ€์‚ฌํ•˜๊ฒŒ๋˜๋Š”๋ฐ isBad(Mid) = True ์ผ๋•Œ ์ƒ๊ฐํ•ด๋ณด์ž

image
  • ์ค‘๊ฐ„ ์ง€์ ์—์„œ ๋ถˆ๋Ÿ‰์ด ๋‚˜์™”๋‹ค๋Š”๋œป์€ ๊ทธ ์ด์ „์— ๋‚˜์™”์„์ˆ˜๋„์žˆ๋‹ค๋Š” ๋œป์ด๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒˆ๋กœ์šด ์ด์ง„ํƒ์ƒ‰ ์˜ 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)


Dynamic Programming

  • 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 (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 ์„ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค.
image
  • Scenario 2 :ฮฃ nums[StartingPointer...Counter] < nums[Counter+1]
    • ์ด์ „์˜ Sum ์ด ๋‹ค์Œ ์š”์†Œ๋ณด๋‹ค ์ž‘๋‹ค๋ฉด, ๋‹ค์Œ ๊ฐ’์„ ์ƒˆ๋กœ์šด ๊ธฐ์ค€์œผ๋กœ ํ•ด์ค˜์•ผํ• ์ง€ ์ƒ๊ฐํ•ด๋ด์•ผํ•œ๋‹ค.
    • ๋งŒ์ผ, ์ด์ „์˜ ํ•ฉ๊ณผ ๋‹ค์Œ์š”์†Œ์˜ ํ•ฉ > ๋‹ค์Œ์š”์†Œ์˜ ๊ฐ’ ์ผ๋•Œ, ๊ธฐ์ค€(StartPointer)์„ ์—…๋ฐ์ดํŠธ ํ•ด์ค„ํ•„์š”๊ฐ€ ์—†๊ฒŒ๋œ๋‹ค.
    • ๋งˆ์ง€๋ง‰์œผ๋กœ ์ด์ „์˜ ํ•ฉ๊ณผ ๋‹ค์Œ์š”์†Œ์˜ ํ•ฉ ๊ณผ ํ˜„์žฌ ๊ธฐ๋ก๋˜์–ด์žˆ๋Š” maxSum ์„ ๋น„๊ตํ•ด์„œ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
image
  • ์ฒ˜์Œ์—” ์ด์ „์˜ ์š”์†Œ๋“ค์˜ ํ•ฉ ์„ ๊ตฌํ• ๋•Œ 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)


Design

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)


Math

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.

image.png

Then I would compute power of that exponent on base 3 to see if the that is equal to n

image.png

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 ๋งˆ๋‹ค ํ• ๋‹น๋˜๋Š” ๊ฐ’์„ ์ง€์ •ํ•ด์ค€๋‹ค.
     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 ์™ธ์˜ ๋‹ค๋ฅธ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•ด์ค„ ํ•„์š”๊ฐ€ ์—†์–ด์ง„๋‹ค.
     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)

Others

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)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages