Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1's in the binary representation of i.
Example 1:
Input: n = 2
Output: [0,1,1]
Explanation:
0 --> 0
1 --> 1
2 --> 10
Example 2:
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
Constraints:
- 0 <= n <= 105
Follow up:
- It is very easy to come up with a solution with a runtime of O(n log n). Can you do it in linear time O(n) and possibly in a single pass?
- Can you do it without using any built-in function (i.e., like __builtin_popcount in C++)?
문제 해설
이 문제는 0부터 nn까지의 정수를 2진수로 변환했을 때, 각 숫자의 1의 개수를 계산하여 배열로 반환하는 문제입니다.
문제 조건
- 입력: 정수 nn (0≤n≤1050 \leq n \leq 10^5).
- 출력: 길이가 n+1n + 1인 배열 ansans로, ans[i]ans[i]는 정수 ii의 이진 표현에서 1의 개수를 나타냅니다.
제한 조건
- O(nlogn)의 복잡도로는 간단하게 해결 가능하지만, 이 문제는 O(n) 시간 복잡도로 해결해야 합니다.
- 내장 함수 (예: __builtin_popcount)를 사용하지 않고 구현해야 합니다.
https://youtu.be/CNHIHRofKdk?si=OnEJ32ZRkdzzE47g
Code
class Solution:
def countBits(self, n: int) -> List[int]:
# DP 배열 초기화: dp[i]는 i의 이진 표현에서 1의 개수를 저장
dp = [0] * (n + 1)
# offset: 현재 참조 중인 가장 큰 2의 거듭제곱
offset = 1
# 1부터 n까지 순회하면서 dp 배열 계산
for i in range(1, n + 1):
# i가 새로운 2의 거듭제곱일 때, offset 업데이트
if offset * 2 == i:
offset = i
# dp[i]는 i의 1의 개수 = dp[i - offset] + 1
# offset은 가장 가까운 2의 거듭제곱
dp[i] = 1 + dp[i - offset]
# 결과 반환: dp 배열
return dp
===============================================================================
class Solution:
def countBits(self, n: int) -> List[int]:
"""
0 -> 0
1 -> 01 -> 1
2 -> 10 -> 1
3 -> 11 -> 2
4 -> 100 -> 1
5 -> 101 -> 2
6 -> 110 -> 2
7 -> 111 -> 3
8 ->1000 -> 1
"""
if n == 0:
return [0]
dp = [0]*(n+1)
dp[1] = 1
for i in range(2, n+1):
dp[i] = dp[i//2] + dp[i%2]
return dp
class Solution:
def countBits(self, n: int) -> List[int]:
"""
0 -> 0
1 -> 01 -> 1
2 -> 10 -> 1
3 -> 11 -> 2
4 -> 100 -> 1
5 -> 101 -> 2
6 -> 110 -> 2
7 -> 111 -> 3
8 ->1000 -> 1
"""
# if n == 0:
# return [0]
dp = [0]*(n+1)
# dp[1] = 1
for i in range(1, n+1):
dp[i] = dp[i//2] + i%2
return dp
191 번 활용
class Solution:
def countBits(self, n: int) -> List[int]:
res = []
def getBits(num):
cnt = 0
while num:
num &= (num-1)
cnt+=1
return cnt
for i in range(n+1):
res.append(getBits(i))
return res
https://youtu.be/RyBM56RIWrM?si=sAnUKsuTKn0gekal
코드 풀이
class Solution:
def countBits(self, n: int) -> List[int]:
""" 1개수
1 - 0001 1 = 1+dp[n-1]
2 - 0010 1 = 1+dp[n-2]
3 - 0011 2 = 1+dp[n-2]
4 - 0100 1 = 1+dp[n-4]
5 - 0101 2 = 1+dp[n-4]
6 - 0110 2 = 1+dp[n-4]
7 - 0111 3
8 - 1000 1 = 1+dp[n-8]
9 - 1001 2
"""
dp = [0] * (n+1)
offset = 1
for i in range(1, n+1):
if offset *2 == i:
offset = i
dp[i] = 1 + dp[i-offset]
return dp
'LeetCode > 주제별 보충' 카테고리의 다른 글
Tree: 1448. Count Good Nodes in Binary Tree (2) | 2024.11.15 |
---|---|
Tree: 104. Maximum Depth of Binary Tree (2) | 2024.11.15 |
DP2D: 1143. Longest Common Subsequence (0) | 2024.11.08 |
DP2D: 62. Unique Paths (0) | 2024.11.08 |
DP1D: 198. House Robber (6) | 2024.11.07 |