Skip to content

Commit 003671d

Browse files
author
mykoo
committed
Merge remote-tracking branch 'upstream/main'
2 parents 1ba0f04 + 171d243 commit 003671d

File tree

18 files changed

+655
-1
lines changed

18 files changed

+655
-1
lines changed

β€Ž.github/workflows/integration.yamlβ€Ž

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ jobs:
1313
label-lang:
1414
runs-on: ubuntu-latest
1515
continue-on-error: true
16+
17+
permissions:
18+
contents: write
19+
pull-requests: write
20+
1621
steps:
1722
- name: Checkout code
1823
uses: actions/checkout@v4
@@ -81,5 +86,5 @@ jobs:
8186
}
8287
}
8388
84-
run().catch(err => console.error(err));
89+
run();
8590
"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Definition for a binary tree node.
2+
class TreeNode {
3+
val: number;
4+
left: TreeNode | null;
5+
right: TreeNode | null;
6+
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
7+
this.val = val === undefined ? 0 : val;
8+
this.left = left === undefined ? null : left;
9+
this.right = right === undefined ? null : right;
10+
}
11+
}
12+
13+
// T.C: O(N)
14+
// S.C: O(N^2) - Slice makes n-1, n-2, ..., 1 for n times. So, it's O(N^2).
15+
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
16+
if (preorder.length === 0 || inorder.length === 0) {
17+
return null;
18+
}
19+
const root = new TreeNode(preorder[0]);
20+
const idx = inorder.indexOf(preorder[0]);
21+
root.left = buildTree(preorder.slice(1, idx + 1), inorder.slice(0, idx));
22+
root.right = buildTree(preorder.slice(idx + 1), inorder.slice(idx + 1));
23+
24+
return root;
25+
}
26+
27+
// Not using slice. but I think it's not necessary... first solution is more readable. and that's not so bad.
28+
// T.C: O(N)
29+
// S.C: O(N)
30+
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
31+
// this tree is consist of unique values
32+
const inorderMap = new Map<number, number>();
33+
for (const [i, val] of inorder.entries()) {
34+
inorderMap.set(val, i);
35+
}
36+
37+
function helper(preLeft: number, preRight: number, inLeft: number, inRight: number): TreeNode | null {
38+
if (preLeft > preRight) return null;
39+
40+
const rootValue = preorder[preLeft];
41+
const root = new TreeNode(rootValue);
42+
const inRootIdx = inorderMap.get(rootValue)!;
43+
44+
const leftSize = inRootIdx - inLeft;
45+
46+
root.left = helper(preLeft + 1, preLeft + leftSize, inLeft, inRootIdx - 1);
47+
root.right = helper(preLeft + leftSize + 1, preRight, inRootIdx + 1, inRight);
48+
49+
return root;
50+
}
51+
52+
return helper(0, preorder.length - 1, 0, inorder.length - 1);
53+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"""TC: O(n), SC: O(n)
2+
3+
아이디어:
4+
- preorder νŠΈλ¦¬κ°€ μ£Όμ–΄μ Έ μžˆλ‹€λ©΄ λ‹€μŒκ³Ό 같이 λΆ„ν• ν•  수 μžˆλ‹€.
5+
- [rootκ°’, [...left], [...right]]
6+
- μœ„μ˜ left, rightλŠ” preorder νŠΈλ¦¬μ™€ 같은 λ°©μ‹μœΌλ‘œ κ΅¬μ„±λœλ‹€.
7+
- inorder νŠΈλ¦¬κ°€ μ£Όμ–΄μ Έ μžˆλ‹€λ©΄ λ‹€μŒκ³Ό 같이 λΆ„ν• ν•  수 μžˆλ‹€.
8+
- [[...left], rootκ°’, [...right]]
9+
- μœ„μ˜ left, rightλŠ” inorder νŠΈλ¦¬μ™€ 같은 λ°©μ‹μœΌλ‘œ κ΅¬μ„±λœλ‹€.
10+
- μ΄λ•Œ,
11+
- left의 첫 μ•„μ΄ν…œμ΄ 인덱슀 inorder_s에 있고,
12+
- right의 λ§ˆμ§€λ§‰ μ•„μ΄ν…œμ΄ 인덱슀 inorder_e - 1에 μžˆλ‹€κ³  ν•˜μž.
13+
- 즉, inorder_eλ₯Ό 미포함!
14+
- preorder 트리의 맨 μ•ž 값을 톡해 rootκ°’ val을 μ°Ύκ³ , 이 κ°’μœΌλ‘œ inorder의 rootκ°’μ˜ 인덱슀λ₯Ό 찾을 수 μžˆλ‹€.
15+
- λͺ¨λ“  node의 val값이 uniqueν•œ 것이 쑰건으둜 μ£Όμ–΄μ Έ μžˆμœΌλ―€λ‘œ valκ°’μ˜ indicesλ₯Ό μ „μ²˜λ¦¬ν•΄λ‘˜ 수 μžˆλ‹€.
16+
- μ΄λ•Œ, inorder의 rootκ°’μ˜ 인덱슀λ₯Ό inorder_root이라고 ν•˜μž.
17+
- inorder의 rootκ°’μ˜ μœ„μΉ˜μ™€ inorder 트리의 μ‹œμž‘ μœ„μΉ˜λ₯Ό μ•Œ 수 μžˆλ‹€λ©΄
18+
[...left]의 길이 left_len을 μ•Œ 수 μžˆλ‹€.
19+
- left_len = inorder_root - inorder_start
20+
- preorder 트리의 left의 λ£¨νŠΈλŠ” [...left]의 첫 μ•„μ΄ν…œ, 즉, preorder_root에 1을 λ”ν•œ 값이닀.
21+
- preorder 트리의 right의 λ£¨νŠΈλŠ” [...right]의 첫 μ•„μ΄ν…œ, 즉, preorder_root + 1 + left_len이닀.
22+
- root값을 ꡬ할 수 μ—†μœΌλ©΄ λ…Έλ“œκ°€ μ—†λ‹€.
23+
- inorder_s >= inorder_e와 같이 νŒλ³„μ΄ κ°€λŠ₯ν•˜λ‹€. 즉, μ•„μ΄ν…œμ΄ ν•˜λ‚˜λ„ μ—†λŠ” 경우.
24+
25+
μœ„μ˜ 아이디어λ₯Ό μ’…ν•©ν•˜λ©΄,
26+
- preorder 트리의 루트 인덱슀 preorder_rootκ°€ μ£Όμ–΄μ§„, ꡬ간 (inorder_s, inorder_e)μ—μ„œ μ •μ˜λœ inorder νŠΈλ¦¬λŠ”
27+
- val값은 preorder[preorder_root]이 λœλ‹€.
28+
- left nodeλŠ” μ•„λž˜μ™€ 같이 ꡬ해진닀.
29+
- preorder 트리의 루트 인덱슀 preorder_root + 1,
30+
- ꡬ간 (inorder_s, inorder_root)
31+
- μ΄λ•Œ ꡬ간이 μœ νš¨ν•˜μ§€ μ•ŠμœΌλ©΄ λ…Έλ“œκ°€ μ—†λ‹€.
32+
- right nodeλŠ” μ•„λž˜μ™€ 같이 ꡬ해진닀.
33+
- preorder 트리의 루트 인덱슀 preorder_root + 1 + left_len,
34+
- ꡬ간 (inorder_root + 1, inorder_end)
35+
- μ΄λ•Œ ꡬ간이 μœ νš¨ν•˜μ§€ μ•ŠμœΌλ©΄ λ…Έλ“œκ°€ μ—†λ‹€.
36+
37+
38+
SC:
39+
- 처음 inorder_indicesλ₯Ό κ³„μ‚°ν• λ•Œ O(n).
40+
- μ•„λž˜μ˜ buildν•¨μˆ˜ 호좜이 μ΅œλŒ€ 트리의 깊이만큼 μž¬κ·€λ₯Ό λŒλ©΄μ„œ μŒ“μΌ 수 μžˆλ‹€.
41+
- 트리의 κΉŠμ΄λŠ” μ΅œμ•…μ˜ 경우 O(n).
42+
43+
TC:
44+
- buildν•¨μˆ˜λŠ” O(1). μ½”λ“œ μ°Έμ‘°.
45+
- μœ„μ˜ 과정을 n개의 λ…Έλ“œμ— λŒ€ν•΄ λ°˜λ³΅ν•˜λ―€λ‘œ O(n).
46+
"""
47+
48+
49+
# Definition for a binary tree node.
50+
# class TreeNode:
51+
# def __init__(self, val=0, left=None, right=None):
52+
# self.val = val
53+
# self.left = left
54+
# self.right = right
55+
class Solution:
56+
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
57+
inorder_indices = {v: i for i, v in enumerate(inorder)}
58+
59+
def build(inorder_s, inorder_e, preorder_root):
60+
if inorder_s >= inorder_e: # O(1)
61+
return None
62+
val = preorder[preorder_root] # O(1)
63+
inorder_root = inorder_indices[val] # O(1)
64+
left_len = inorder_root - inorder_s # O(1)
65+
return TreeNode(
66+
val,
67+
left=build(inorder_s, inorder_root, preorder_root + 1),
68+
right=build(inorder_root + 1, inorder_e, preorder_root + 1 + left_len),
69+
)
70+
71+
return build(0, len(inorder), 0)
72+
73+
74+
"""
75+
그런데 μœ„μ˜ 아이디어λ₯Ό λ‹€μ‹œ 생각해보면, λͺ¨λ“  λ…Έλ“œλ“€μ„ preorder μˆœμ„œλ‘œ μˆœνšŒν•œλ‹€!
76+
- `val = preorder[preorder_root]`와 같은 λ°©μ‹μœΌλ‘œ val값을 κ΅¬ν•˜μ§€ μ•Šκ³ , μ£Όμ–΄μ§„ preorderλ₯Ό μˆœμ„œλŒ€λ‘œ 가져와도 됨.
77+
- 즉, preorderλ₯Ό iterator둜 λ°”κΏ”μ„œ nextλ₯Ό 톡해 값을 ν•˜λ‚˜μ”© λ½‘μ•„μ™€μ„œ κ±΄λ„€μ€˜λ„ λœλ‹€.
78+
- μ΄λ ‡κ²Œ ν•˜λ©΄ buildν•¨μˆ˜μ— preorder_rootλ₯Ό μ „λ‹¬ν•˜μ§€ μ•Šμ•„λ„ 됨.
79+
"""
80+
81+
82+
class Solution:
83+
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
84+
inorder_indices = {v: i for i, v in enumerate(inorder)}
85+
preorder_iter = iter(preorder)
86+
87+
def build(inorder_s, inorder_e):
88+
if inorder_s >= inorder_e: # O(1)
89+
return None
90+
val = next(preorder_iter) # O(1)
91+
inorder_root = inorder_indices[val] # O(1)
92+
return TreeNode(
93+
val,
94+
left=build(inorder_s, inorder_root),
95+
right=build(inorder_root + 1, inorder_e),
96+
)
97+
98+
return build(0, len(inorder))
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
class TreeNode {
2+
val: number;
3+
left: TreeNode | null;
4+
right: TreeNode | null;
5+
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
6+
this.val = val === undefined ? 0 : val;
7+
this.left = left === undefined ? null : left;
8+
this.right = right === undefined ? null : right;
9+
}
10+
}
11+
12+
/**
13+
* preorder: [root, left, right]
14+
* inorder: [left, root, right]
15+
* preorder의 첫번째 값은 root이닀. (1. ν˜„μž¬ root μ°ΎκΈ°)
16+
* λͺ¨λ“  node의 valλŠ” uniqueν•˜κΈ° λ•Œλ¬Έμ— 이 값을 κΈ°μ€€μœΌλ‘œ inorderμ—μ„œ root의 μœ„μΉ˜λ₯Ό 찾을 수 μžˆλ‹€.
17+
*
18+
* inorderμ—μ„œ root의 μœ„μΉ˜λ₯Ό 찾으면, rootλ₯Ό κΈ°μ€€μœΌλ‘œ μ™Όμͺ½μ€ left subtree, 였λ₯Έμͺ½μ€ right subtree이닀. (2. left subtree, right subtree ꡬ뢄)
19+
* inorder: [...left, root, ...right]
20+
* root값은 이미 μ°Ύμ•˜κΈ° λ•Œλ¬Έμ— shift둜 μ œκ±°ν•œλ‹€.
21+
*
22+
* 남은 preorderμ—μ„œ 첫번째 값은 left subtree의 root이닀. (3. left subtree ꡬ성)
23+
* preorderμ—μ„œ ν•˜λ‚˜μ”© shiftν•˜λ©΄μ„œ μ™Όμͺ½ 트리λ₯Ό λ¨Όμ € κ΅¬μ„±ν•œλ‹€.
24+
* preorderμ—μ„œ 첫번째 값이 μ™Όμͺ½ subtree의 root이닀. (1. ν˜„μž¬ root μ°ΎκΈ°)
25+
* inorderμ—μ„œ root의 μœ„μΉ˜λ₯Ό μ°Ύμ•„μ„œ μ™Όμͺ½ subtreeλ₯Ό κ΅¬μ„±ν•œλ‹€. (2. left subtree, right subtree ꡬ뢄) (3. left subtree ꡬ성)
26+
* root κΈ°μ€€ μ™Όμͺ½ subtree ꡬ성이 λλ‚˜λ©΄ 였λ₯Έμͺ½ subtreeλ₯Ό κ΅¬μ„±ν•œλ‹€.
27+
* μœ„ 과정을 μž¬κ·€μ μœΌλ‘œ λ°˜λ³΅ν•˜λ©΄, 전체 트리λ₯Ό ꡬ성할 수 μžˆλ‹€. (1-3 κ³Όμ • 반볡)
28+
*/
29+
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
30+
// build ν•¨μˆ˜κ°€ 각 λ…Έλ“œλ§ˆλ‹€ 호좜됨(N) * 각 λ…Έλ“œλ§ˆλ‹€ shift, indexOf μˆ˜ν–‰(N) = O(N^2)
31+
function build(preorder, inorder) {
32+
if (inorder.length) {
33+
// TC: O(N)
34+
const idx = inorder.indexOf(preorder.shift());
35+
const root = new TreeNode(inorder[idx]);
36+
37+
root.left = build(preorder, inorder.slice(0, idx));
38+
root.right = build(preorder, inorder.slice(idx + 1));
39+
40+
return root;
41+
}
42+
return null;
43+
}
44+
45+
return build(preorder, inorder);
46+
}
47+
48+
// TC: O(N^2)
49+
// SC: O(N^2)

β€Žcounting-bits/HC-kang.tsβ€Ž

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// T.C: O(n)
2+
// S.C: O(n)
3+
function countBits(n: number): number[] {
4+
// T.C: O(1)
5+
// S.C: O(1)
6+
function countBit(num: number): number {
7+
num = num - ((num >>> 1) & 0x55555555);
8+
num = (num & 0x33333333) + ((num >>> 2) & 0x33333333);
9+
num = (num + (num >>> 4)) & 0x0f0f0f0f;
10+
num = num + (num >>> 8);
11+
num = num + (num >>> 16);
12+
return num & 0x3f;
13+
}
14+
15+
return new Array(n + 1).fill(0).map((_, i) => countBit(i));
16+
}
17+
18+
// T.C: O(n)
19+
// S.C: O(n)
20+
function countBits(n: number): number[] {
21+
const dp = new Array(n + 1).fill(0);
22+
for (let i = 1; i <= n; i++) {
23+
dp[i] = dp[i >> 1] + (i & 1);
24+
}
25+
return dp;
26+
}

β€Žcounting-bits/haklee.pyβ€Ž

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""TC: O(n), SC: O(n)
2+
3+
아이디어:
4+
- bin으둜 λ³€ν™˜ν•œ κ°’μ˜ 길이가 k인 λͺ¨λ“  μˆ˜λ“€μ— λŒ€ν•œ bit_count값을 μ•Œκ³  μžˆλ‹€κ³  ν•˜μž.
5+
- 사싀 μœ„μ˜ μˆ˜λ“€μ€ bin으둜 λ³€ν™˜ν–ˆμ„λ•Œ 맨 μ•ž μžλ¦¬κ°€ 0으둜 μ‹œμž‘ν•˜λŠ” 길이 k+1의 수라고 λ³Ό 수 μžˆλ‹€.
6+
- κ·Έλ ‡λ‹€λ©΄ bin으둜 λ³€ν™˜ν–ˆμ„λ•Œ 맨 μ•ž μžλ¦¬κ°€ 1둜 μ‹œμž‘ν•˜λŠ” 길이 k+1인 μˆ˜λ“€μ˜ bit_countλŠ”
7+
맨 μ•ž μžλ¦¬κ°€ 0으둜 μ‹œμž‘ν•˜λŠ” μˆ˜λ“€μ˜ bit_count에 1을 λ”ν•œ 것이라고 ν•  수 μžˆλ‹€.
8+
- μœ„μ˜ 아이디어λ₯Ό ν™œμš©ν•˜λ©΄ μ•ž 2^k μˆ˜λ“€μ˜ bit_countλ₯Ό μ•Œκ³  있으면 κ°„λ‹¨ν•œ λ”ν•˜κΈ° 연산을 톡해
9+
이후 2^k μˆ˜λ“€μ˜ bit_count값도 μ•Œ 수 μžˆλ‹€.
10+
e.g.)
11+
- 0, 1의 bit_countκ°€ [0, 1]이라면, 2, 3의 bit_countλŠ” [0+1, 1+1], 즉, 0~3의 bit_countλŠ” [0, 1, 1, 2]
12+
- 0~3의 bit_countκ°€ [0, 1, 1, 2]라면, 4~7의 bit_countλŠ” [1, 2, 2, 3], 즉, 0~7의 bit_countλŠ”
13+
[0, 1, 1, 2, 1, 2, 2, 3]
14+
- ...
15+
- 리슀트의 크기λ₯Ό 2λ°°μ”© λŠ˜λ¦¬λ‹€κ°€ n보닀 μ»€μ‘Œμ„λ•Œ μ•ž n개의 μ•„μ΄ν…œλ§Œ μ·¨ν•΄μ„œ 리턴.
16+
17+
18+
SC:
19+
- μ•„λž˜μ—μ„œ 리슀트 s의 κΈΈμ΄λŠ” 2^(k-1) < n <= 2^kλ₯Ό λ§Œμ‘±ν•˜λŠ” 2^k만큼 컀진닀.
20+
- 즉, O(n).
21+
22+
TC:
23+
- s μ•ˆμ— λ“€μ–΄μžˆλŠ” i번째 μ•„μ΄ν…œμ„ κ³„μ‚°ν• λ•Œ ν•„μš”ν•œ 연산은 λ§μ…ˆ 1회, 즉, O(1).
24+
- i번째 μ•„μ΄ν…œ 값을 κ΅¬ν•˜κΈ° μœ„ν•΄ κ·Έ μ•žμ˜ 값을 미리 계산해둔 것이라 생각할 수 μžˆλ‹€.
25+
- SC 뢄석과 λΉ„μŠ·ν•˜κ²Œ, 2^(k-1) < n <= 2^kλ₯Ό λ§Œμ‘±ν•˜λŠ” 2^k만큼 반볡. 즉, O(n).
26+
"""
27+
28+
29+
class Solution:
30+
def countBits(self, n: int) -> List[int]:
31+
s = [0]
32+
m = n * 2
33+
while m := m >> 1:
34+
s += [i + 1 for i in s]
35+
return s[: n + 1]

β€Žcounting-bits/jaejeong1.javaβ€Ž

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class SolutionCountingBits {
2+
public int[] countBits(int n) {
3+
// 0 ~ n κΉŒμ§€μ˜ 수λ₯Ό μ΄μ§„μˆ˜λ‘œ λ³€ν™˜ν•œλ‹€μŒ, 1의 개수λ₯Ό μΉ΄μš΄νŠΈν•΄ λ°°μ—΄λ‘œ λ°˜ν™˜
4+
// ν™€μˆ˜/짝수 μ—¬λΆ€λ₯Ό λ‚˜λˆ μ„œ 1의 개수λ₯Ό ꡬ함
5+
// ν™€μˆ˜: 이전 κ°’ + 1, 짝수: i / 2의 1의 κ°œμˆ˜μ™€ 같은 κ°’
6+
// μ‹œκ°„λ³΅μž‘λ„: O(N), κ³΅κ°„λ³΅μž‘λ„: O(N)
7+
8+
int[] countingBits = new int[n + 1];
9+
countingBits[0] = 0;
10+
11+
for (int i=1; i<=n; i++) {
12+
if (isOddNumber(i)) {
13+
countingBits[i] = countingBits[i - 1] + 1;
14+
} else {
15+
countingBits[i] = countingBits[i / 2];
16+
}
17+
}
18+
19+
return countingBits;
20+
}
21+
22+
// μ‹œκ°„λ³΅μž‘λ„: O(1)
23+
private boolean isOddNumber(int n) {
24+
return n % 2 == 1;
25+
}
26+
}

β€Žcounting-bits/whewchews.tsβ€Ž

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function countBits(n: number): number[] {
2+
// SC: O(N)
3+
const ans = Array(n + 1).fill(0);
4+
// TC: O(N)
5+
for (let i = 1; i <= n; i++) {
6+
let k = i;
7+
8+
// TC: O(log N)
9+
while (k > 0) {
10+
ans[i] += k % 2;
11+
k = Math.floor(k / 2);
12+
}
13+
}
14+
15+
return ans;
16+
}
17+
18+
// TC: O(N log N)
19+
// SC: O(N)

β€Ždecode-ways/HC-kang.tsβ€Ž

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// T.C: O(n)
2+
// S.C: O(n)
3+
function numDecodings(s: string): number {
4+
const NUM_OF_ALPHA = 26;
5+
const memo = new Map<number, number>();
6+
7+
function dfs(idx: number): number {
8+
if (idx === s.length) {
9+
return 1;
10+
}
11+
if (s[idx] === '0') {
12+
return 0;
13+
}
14+
if (memo.has(idx)) {
15+
return memo.get(idx)!;
16+
}
17+
18+
let count = dfs(idx + 1);
19+
if (
20+
idx + 2 <= s.length && // check if idx + 2 is in the range
21+
parseInt(s.slice(idx, idx + 2), 10) <= NUM_OF_ALPHA
22+
) {
23+
count += dfs(idx + 2);
24+
}
25+
26+
memo.set(idx, count);
27+
return count;
28+
}
29+
30+
return dfs(0);
31+
}

β€Ždecode-ways/haklee.pyβ€Ž

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""TC: O(n), SC: O(1)
2+
3+
아이디어:
4+
λ’· k개의 κΈ€μžλ₯Ό λ””μ½”λ”© ν•˜λŠ” 경우의 수λ₯Ό f(k)라고 ν•˜μž.
5+
f(k)λŠ” λ‹€μŒμ˜ 두 경우의 수λ₯Ό λ”ν•œ 값이닀.
6+
- λ’· k개의 κΈ€μž 쀑 첫 κΈ€μžκ°€ λ””μ½”λ”© κ°€λŠ₯ν•œ 경우, λ’· k-1κΈ€μžλ₯Ό λ””μ½”λ”©ν•˜λŠ” 경우의 수
7+
- λ’· k개의 κΈ€μž 쀑 μ•ž 두 κΈ€μžκ°€ λ””μ½”λ”© κ°€λŠ₯ν•œ 경우, λ’· k-2κΈ€μžλ₯Ό λ””μ½”λ”©ν•˜λŠ” 경우의 수
8+
즉, f(k) = (μ•ž 두 κΈ€μž νŒλ³„)*f(k-2) + (μ•ž ν•œ κΈ€μž νŒλ³„)*f(k-1)
9+
10+
11+
SC:
12+
- tabulation κ³Όμ •μ—μ„œ κ°’ 2개만 계속 μœ μ§€ν•œλ‹€.
13+
- 즉, O(1).
14+
15+
TC:
16+
- f(k) κ΅¬ν•˜λŠ” 식: O(1)
17+
- 두 κΈ€μžκ°€ λ””μ½”λ”© κ°€λŠ₯ν•œμ§€ νŒλ³„: O(1)
18+
- 첫 κΈ€μžκ°€ λ””μ½”λ”© κ°€λŠ₯ν•œμ§€ νŒλ³„: O(1)
19+
- μœ„μ˜ f(k)λ₯Ό κ΅¬ν•˜λŠ” 것을 s의 κΈΈμ΄μ—μ„œ 2λ₯Ό λΊ€ 수만큼 루프, 즉, O(n)
20+
- μ’…ν•©ν•˜λ©΄ O(n).
21+
"""
22+
23+
24+
class Solution:
25+
def numDecodings(self, s: str) -> int:
26+
# init
27+
x, y = 1, int(int(s[-1]) != 0) # f(0), f(1)
28+
# tabulation
29+
for i in range(len(s) - 2, -1, -1): # λ’· k개 κΈ€μžμ˜ μ‹œμž‘ κΈ€μžκ°€ s[i]
30+
# f(k-2), f(k-1)을 f(k-1), f(k)둜
31+
x, y = y, (x * (10 <= int(s[i : i + 2]) <= 26)) + (y * (int(s[i]) != 0))
32+
return y

0 commit comments

Comments
Β (0)