Skip to content

Commit

Permalink
Merge branch 'feat/week2'
Browse files Browse the repository at this point in the history
  • Loading branch information
changmuk.im committed Aug 25, 2024
2 parents 90e72e8 + 816ec49 commit 8ed3ebe
Show file tree
Hide file tree
Showing 8 changed files with 572 additions and 0 deletions.
84 changes: 84 additions & 0 deletions construct-binary-tree-from-preorder-and-inorder-traversal/EGON.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from typing import List, Optional
from unittest import TestCase, main


# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right


class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
return self.solve_1(preorder, inorder)

"""
Runtime: 112 ms (Beats 66.16%)
Time Complexity: O(n ** 2)
Space Complexity: O(n)
Memory: 52.83 MB (Beats 63.14%)
"""
def solve_1(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
index = 0

def build_tree(preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
nonlocal index

if not inorder:
return None

if not 0 <= index < len(preorder):
return None

root = TreeNode(preorder[index])
index += 1
split_index = inorder.index(root.val)
root.left = build_tree(preorder, inorder[:split_index])
root.right = build_tree(preorder, inorder[split_index + 1:])

return root

return build_tree(preorder, inorder)


class _LeetCodeTestCases(TestCase):
def test_1(self):
preorder = [3, 9, 20, 15, 7]
inorder = [9, 3, 15, 20, 7]
output = TreeNode(
val=3,
left=TreeNode(
val=9
),
right=TreeNode(
val=20,
left=TreeNode(val=15),
right=TreeNode(val=7)
)
)
self.assertEqual(Solution.buildTree(Solution(), preorder, inorder), output)

def test_2(self):
preorder = [-1]
inorder = [-1]
output = TreeNode(
val=-1
)
self.assertEqual(Solution.buildTree(Solution(), preorder, inorder), output)

def test_3(self):
preorder = [1, 2]
inorder = [1, 2]
output = TreeNode(
val=1,
right=TreeNode(
val=2
)
)
self.assertEqual(Solution.buildTree(Solution(), preorder, inorder), output)


if __name__ == '__main__':
main()
39 changes: 39 additions & 0 deletions counting-bits/EGON.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from typing import List
from unittest import TestCase, main


class Solution:
def countBits(self, n: int) -> List[int]:
return self.solve_1(n)

"""
Runtime: 78 ms (Beats 31.22%)
Time Complexity: O(n * log n), 크기가 n인 배열의 원소들에 대해 시행마다 크기가 2로 나누어지는 비트연산을 수행하므로
Space Complexity: O(1), 변수 저장 없이 바로 결과 반환
Memory: 23.26 MB (Beats 39.52%)
"""
def solve_1(self, n: int) -> List[int]:
def count_number_of_1(n: int):
count = 0
while n:
n &= (n - 1)
count += 1
return count

return [count_number_of_1(num) for num in range(n + 1)]


class _LeetCodeTestCases(TestCase):
def test_1(self):
n = 2
output = [0, 1, 1]
self.assertEqual(Solution.countBits(Solution(), n), output)

def test_2(self):
n = 5
output = [0, 1, 1, 2, 1, 2]
self.assertEqual(Solution.countBits(Solution(), n), output)


if __name__ == '__main__':
main()
113 changes: 113 additions & 0 deletions counting-bits/EGON.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import Foundation

class Solution {
func countBits(_ n: Int) -> [Int] {
return solve_2(n)
}

/*
**내장함수를 사용한 풀이**

Runtime: 37 ms (Beats 49.12%)
Time Complexity: O(n * log n)
- 길이가 n인 range를 순회하므로 O(n)
- 정수에 대해 non zero bit를 세는데 O(log n)
> O(n * log n)
Space Complexity: O(n)
- 배열에 값을 저장하며 크기가 n이 되므로 O(n)
Memory: 20.86 MB (Beats 90.106%)
*/
func solve_1(_ n: Int) -> [Int] {
var result: [Int] = []
for num in 0...n {
result.append(num.nonzeroBitCount)
}
return result
}

/*
** Brian Kernighan's Algorithm을 사용한 풀이 **

Runtime: 39 ms (Beats 42.11%)
Time Complexity: O(n * log n)
- 길이가 n인 range를 순회하므로 O(n)
- bitCountWithBrianKernighan 에서 내부 while문 실행마다 num이 절반으로 줄어드므로, 실행횟수는 O(log n)
> O(n * log n)
Space Complexity: O(n)
- 배열에 값을 저장하며 크기가 n이 되므로 O(n)
Memory: 16.01 MB (Beats 67.84%)
*/
func solve_2(_ n: Int) -> [Int] {

func bitCountWithBrianKernighan(_ num: Int) -> Int {
var num = num
var bitCount = 0
while 0 < num {
num &= (num - 1)
bitCount += 1
}

return bitCount
}

var result: [Int] = []
for num in 0...n {
result.append(bitCountWithBrianKernighan(num))
}
return result
}

/*
** MSB에 대해 DP를 사용한 풀이 **
> num의 비트 카운트 = MSB의 비트 카운트(1 고정) + (num - msb)의 비트 카운트

Runtime: 36 ms (Beats 58.48%)
Time Complexity: O(n)
- 0부터 n까지 range를 순회하므로 O(n)
> O(n)
Space Complexity: O(n)
- 길이가 n인 dp 배열을 저장하므로 O(n)
Memory: 21.15 MB (Beats 67.84%)
*/
func solve_3(_ n: Int) -> [Int] {
guard 1 <= n else { return [0] }

var dp = [Int](repeating: 0, count: n + 1)
var msb = 1
for num in 1...n {
if msb << 1 == num {
msb = num
}

dp[num] = 1 + dp[num - msb]
}

return dp
}

/*
** LSB에 대해 DP를 사용한 풀이 **
> num의 비트 카운트 = num을 right shift한 숫자의 비트 카운트 + LSB의 비트 카운트(1 또는 0)

Runtime: 28 ms (Beats 97.08%)
Time Complexity: O(n)
- 0부터 n까지 range를 순회하므로 O(n)
> O(n)
Space Complexity: O(n)
- 길이가 n인 dp 배열을 저장하므로 O(n)
Memory: 21.26 MB (Beats 53.80%)
*/
func solve_4(_ n: Int) -> [Int] {
guard 1 <= n else { return [0] }

var dp = [Int](repeating: 0, count: n + 1)
for num in 1...n {
dp[num] = dp[num >> 1] + (num & 1)
}

return dp
}
}

let solution = Solution()
print(solution.solve_4(0))
65 changes: 65 additions & 0 deletions decode-ways/EGON.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from typing import List
from unittest import TestCase, main


class Solution:
def numDecodings(self, s: str) -> int:
return self.solve_1(s)

"""
Runtime: 32 ms (Beats 80.36%)
Time Complexity: O(n)
Space Complexity: O(n)
Memory: 16.59 MB (Beats 51.72%)
"""
def solve_1(self, s: str) -> int:
if len(s) == 0:
return 0

if len(s) == 1:
return 0 if int(s) == 0 else 1

if len(s) == 2:
last_one_digit, last_two_digits = int(s[1]), int(s)
if last_one_digit == 0:
return 1 if 10 <= last_two_digits <= 26 else 0
else:
if 0 <= last_two_digits < 10:
return 0
elif 10 <= last_two_digits <= 26:
return 2
else:
return 1

dp = [0] * (len(s) + 1)
dp[0], dp[1], dp[2] = self.solve_1(s[:0]), self.solve_1(s[:1]), self.solve_1(s[:2])
for i in range(3, len(s) + 1):
last_one_digit, last_two_digits = int(s[i - 1]), int(s[i - 2: i])
last_two_digits = int(s[i - 2: i])
if last_one_digit == 0:
dp[i] += dp[i - 2] if 10 <= last_two_digits <= 26 else 0
else:
dp[i] += dp[i - 1] + (dp[i - 2] if 10 <= last_two_digits <= 26 else 0)

return dp[-1]


class _LeetCodeTestCases(TestCase):
def test_1(self):
s = "226"
output = 3
self.assertEqual(Solution.numDecodings(Solution(), s), output)

def test_2(self):
s = "2101"
output = 1
self.assertEqual(Solution.numDecodings(Solution(), s), output)

def test_3(self):
s = "06"
output = 0
self.assertEqual(Solution.numDecodings(Solution(), s), output)


if __name__ == '__main__':
main()
Loading

0 comments on commit 8ed3ebe

Please sign in to comment.