diff --git a/container-with-most-water/sonjh1217.swift b/container-with-most-water/sonjh1217.swift new file mode 100644 index 000000000..668568c96 --- /dev/null +++ b/container-with-most-water/sonjh1217.swift @@ -0,0 +1,27 @@ +class Solution { + func maxArea(_ height: [Int]) -> Int { + var heights = height + var start = 0 + var end = heights.count - 1 + var maxAmount = 0 + + while start < end { + let startHeight = heights[start] + let endHeight = heights[end] + let amount = min(startHeight, endHeight) * (end - start) + maxAmount = max(amount, maxAmount) + + if startHeight < endHeight { + start += 1 + } else { + end -= 1 + } + } + + return maxAmount + + //시간 O(n) + //공간 O(1) + } +} + diff --git a/design-add-and-search-words-data-structure/sonjh1217.swift b/design-add-and-search-words-data-structure/sonjh1217.swift new file mode 100644 index 000000000..2d01724d5 --- /dev/null +++ b/design-add-and-search-words-data-structure/sonjh1217.swift @@ -0,0 +1,55 @@ +class WordDictionary { + class TrieNode { + var children: [Character: TrieNode] = [:] + var isEndOfWord = false + } + + private var root: TrieNode + + init() { + root = TrieNode() + } + + // O(n) time / O(n) space + func addWord(_ word: String) { + var node = root + + for character in word { + if node.children[character] == nil { + node.children[character] = TrieNode() + } + + node = node.children[character]! + } + + node.isEndOfWord = true + } + + // O(m) ~ O(26^m) time / O(m) space + func search(_ word: String) -> Bool { + return dfs(word: Array(word), index: 0, node: root) + } + + private func dfs(word: [Character], index: Int, node: TrieNode) -> Bool { + if index == word.count { + return node.isEndOfWord + } + + let character = word[index] + + if character == "." { + for child in node.children.values { + if dfs(word: word, index: index + 1, node: child) { + return true + } + } + return false + } else { + guard let child = node.children[character] else { + return false + } + return dfs(word: word, index: index + 1, node: child) + } + } +} + diff --git a/group-anagrams/sonjh1217.swift b/group-anagrams/sonjh1217.swift index 7682acb6e..6d5d763af 100644 --- a/group-anagrams/sonjh1217.swift +++ b/group-anagrams/sonjh1217.swift @@ -2,7 +2,7 @@ class Solution { func groupAnagrams(_ strs: [String]) -> [[String]] { var stringsByCount = [[Int]: [String]]() - strs.map { str in + strs.forEach { str in var countsByAlphabet = Array(repeating: 0, count: 26) for char in str.unicodeScalars { countsByAlphabet[Int(char.value) - 97] += 1 diff --git a/longest-increasing-subsequence/sonjh1217.swift b/longest-increasing-subsequence/sonjh1217.swift new file mode 100644 index 000000000..e20fa67c1 --- /dev/null +++ b/longest-increasing-subsequence/sonjh1217.swift @@ -0,0 +1,41 @@ +class Solution { + // O(nlogn) time / O(n) space + func lengthOfLIS(_ nums: [Int]) -> Int { + var piles: [Int] = [] + // Patience(1인 카드놀이) sort 이용 + for num in nums { + let leftInsertion = binarySearch(piles: piles, target: num) + + // piles[k] >= x인 pile이 없을 때만 append(길이 증가) + if leftInsertion == piles.count { + piles.append(num) + } else { + //가장 왼쪽의 piles[k] >= x 위치에 교체 + piles[leftInsertion] = num + } + + } + + // piles[k] = 길이 (k+1) 증가수열이 가질 수 있는 '끝값의 최소치' + // sort 로직상 piles.count가 최대한 길게 만들었기 때문에 piles.count는 가장 긴 길이가 됨 + return piles.count + } + + func binarySearch(piles: [Int], target: Int) -> Int { + var left = 0 + + //target의 삽입 위치고 맨 끝에 덧붙일수도 있어서 nums.count - 1 이 아님 + var right = piles.count + + while left < right { + let mid = left + (right - left) / 2 + if target > piles[mid] { + left = mid + 1 + } else { + //맨 왼쪽 거를 찾아야 함으로 다시 쪼개가면서 맨 왼쪽 거를 찾는다. 맨 왼쪽 거에 넣어야 길이(k) 증가수열의 끝값이 가장 작게 된다. 이래야 최대한 뒤에 계속 더 이어붙여서 최대한 길게 piles를 만들 수 있음. + right = mid + } + } + return left + } +} diff --git a/valid-parentheses/sonjh1217.swift b/valid-parentheses/sonjh1217.swift new file mode 100644 index 000000000..05ef347f2 --- /dev/null +++ b/valid-parentheses/sonjh1217.swift @@ -0,0 +1,22 @@ +class Solution { + func isValid (_ s: String) -> Bool { + var brackets: [Character: Character] = ["(": ")", "[": "]", "{": "}"] + var closers = [Character]() + + for character in s { + if let closer = brackets[character] { + closers.append(closer) + } else if character == closers.last { + closers.removeLast() + } else { + return false + } + } + + return closers.isEmpty + + //시간 O(n) (string의 길이) + //공간 O(n) + } +} +