Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- binary tree
- matrix
- Binary
- two pointers
- Array
- 쉬움
- backtracking
- linked list
- 이진트리
- sorting
- leetcode
- Medium
- HashTable
- list
- 리트코드
- tree
- string
- 문자열
- 미디움
- DP
- 중간
- easy
- binary search
- hash table
- Depth-first Search
- math
- recursive
- 재귀
- Python
- dfs
Archives
- Today
- Total
부부의 코딩 성장 일기
LeetCode 137(Single Number II, Python) 본문
1. 문제 링크
Single Number II - LeetCode
Can you solve this real interview question? Single Number II - Given an integer array nums where every element appears three times except for one, which appears exactly once. Find the single element and return it. You must implement a solution with a lin
leetcode.com
2. 문제 설명
- 정수로 구성된 array nums가 주어졌을 때, 한 개의 element를 제외하고는, 모두 3번씩 등장한다고 할 때,
- 3번 등장하지 않은 element를 찾아서 반환
- 예시1) nums = [2,2,3,2]이면, 3만 한 번 등장했으므로, 3을 반환
- 예시2) nums = [0,1,0,1,0,1,99]이면, 99만 한 번 등장했으므로, 99를 반환
- 여기서 중요한 점은, linear runtime complexity를 가져야 하고, 오직 상수 공간만 사용할 수 있다는 제한이다. (runtime compexity O(N), space complexity O(1)이 되는 것)
3. 처음 풀이
- O(1)의 공간복잡도로 푸는 것은 결국 떠올리지 못했고,
- dictionary에 hist를 저장하면서 만약 value가 3이 아니면, 해당 값을 return하는 방식으로 해결했다.
- 그래도 leetcode runtime은 나쁘지 않았고, 다른 분들 풀이도, 공간 복잡도 O(1)을 지키지 않은듯 했다.
class Solution:
def singleNumber(self, nums: List[int]) -> int:
history = {}
for index,i in enumerate(nums):
if i not in history:
history[i] = 1
else:
history[i] +=1
for i in history:
if history[i] != 3:
return i
4. 다른 풀이
- 그럼에도 가장 빠른 풀이는, 공간복잡도 O(1)을 갖는, 비트연산자를 활용한 풀이었다.
- 비트연산자는 항상 먼저 풀이를 떠올리기가 참 어렵다.
def singleNumber(nums):
ones = 0
twos = 0
for num in nums:
ones = (ones ^ num) & ~twos
twos = (twos ^ num) & ~ones
return ones
- 한번 나타난 비트 처리 (ones 변수 업데이트)
- 현재 비트가 처음 나타났으면, ones에 해당 비트를 저장
- 현재 비트가 이미 있었으면, ones에서 그 비트를 제거
- 두번 나타난 비트 처리 (twos 변수 업데이트)
- 현재 비트가 처음 나타났으면, twos에 그 비트 저장
- 현재 비트가 이미 나타났다면, twos에서 그 비트 제거
- 세번 이상 나타난 비트는,
- ones, twos 동시에 특정 비트가 설정되있으면, 해당 비트가 세번 이상 나타났다는 것으로, 해당 비트 제거하여 초기화
- 결과적으로 ones 변수에는 한 번 나타난 비트만 남게 되므로, 모든 요소에 대해 반복한 뒤, ones를 리턴한다.
- 이걸 어떻게 떠올리지.. 아직 직관적으로 이해가 안간다. 어려운 문제라 생각한다.
5. 배운 점
- 비트 연산자. 익숙해지기
'Algorithm > LeetCode' 카테고리의 다른 글
LeetCode 350(Intersection of Two Arrays II, Python) (1) | 2024.03.23 |
---|---|
LeetCode 349(Intersection of Two Arrays, Python) (1) | 2024.03.22 |
LeetCode 131(Palindrome Partitioning, Python) (0) | 2024.03.15 |
LeetCode 326(Power of Three, Python) (0) | 2024.03.13 |
LeetCode 292(Nim Game, Python) (0) | 2024.03.11 |