Skip to content

Commit 74e043b

Browse files
Add longest-consecutive-sequence
1 parent 89f249d commit 74e043b

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
longest-consecutive-sequence
3+
요구사항: 주어진 비정렬 배열에서 가장 긴 연속 수열의 길이를 O(N)에 구하라.
4+
접근 1: 가장 단순한 방법은 정렬 후 스캔하여 가장 긴 연속 구간을 찾는 것이다.
5+
정렬 비용 O(NlogN)에 스캔 O(N)으로 총 O(NlogN)이다. 비용 초과.
6+
접근 2: 정렬하지 않고, 인접한 연속 원소 수열을 '하나의 덩어리'로 취급하기 위해 union-find할 수 있다.
7+
중복 원소는 무시한다.
8+
입력 x에 대해 x-1의 유니온을 찾는다.
9+
그러한 유니온이 존재하면 x를 추가한다. 그 이후 x+1 유니온이 존재하면 통합한다.
10+
그러한 유니온이 존재하지 않으면 x+1 유니온을 찾는다.
11+
그러한 유니온이 존재하면 x를 추가한다.
12+
인접한 앞 뒤 유니온이 존재하지 않으면 입력을 새로운 root union으로 초기화한다.
13+
14+
비용:
15+
경로 압축과 높이 최소화 최적화를 적용하면, find 비용은 O(α(N))으로 최대 입력 N=10^5에 대해서 한 자리 상수만큼 충분히 낮다.
16+
유니온의 통합 비용은 O(1)이다.
17+
N개의 입력에 대해 O(1) 연산을 상수 ㅣ 수행하므로 유니온 빌딩 시간 복잡도는 O(N)이다.
18+
사이즈 리스트를 스캔하여 가장 큰 유니온의 크기를 구한다. 이는 O(K) where K <= N이다.
19+
따라서 총 시간 복잡도는 O(N)이다.
20+
공간 복잡도도 입력 범위의 상수배이므로 O(N)이다.
21+
*/
22+
23+
#include <unordered_map>
24+
#include <vector>
25+
26+
#define max(a, b) ((a) > (b) ? (a) : (b))
27+
28+
class Solution {
29+
public:
30+
std::unordered_map<int, int> parent;
31+
std::unordered_map<int, int> size;
32+
33+
int find(int x) {
34+
if (x == parent[x]) return x;
35+
return parent[x] = find(parent[x]); // path compression
36+
}
37+
void union_sets(int x, int y) {
38+
int px = find(x);
39+
int py = find(y);
40+
41+
if (px == py) return;
42+
43+
// min height optimization
44+
if (size[px] > size[py]) {
45+
size[px] += size[py];
46+
parent[py] = px;
47+
} else {
48+
size[py] += size[px];
49+
parent[px] = py;
50+
}
51+
}
52+
int longestConsecutive(std::vector<int>& nums) {
53+
// build union
54+
for (auto it = nums.begin(); it != nums.end(); it++) {
55+
int x = *it;
56+
57+
if (parent.find(x) != parent.end())
58+
continue;
59+
60+
if (parent.find(x - 1) != parent.end()) {
61+
parent[x] = find(x - 1);
62+
size[parent[x]]++;
63+
if (parent.find(x + 1) != parent.end()) {
64+
union_sets(x, x + 1);
65+
}
66+
} else if (parent.find(x + 1) != parent.end()) {
67+
parent[x] = find(x + 1);
68+
size[parent[x]]++;
69+
} else {
70+
parent[x] = x;
71+
size[x] = 1;
72+
}
73+
}
74+
75+
// find largest set
76+
int max_size = 0;
77+
for(auto it = size.begin(); it != size.end(); it++) {
78+
auto sz = it->second;
79+
max_size = max(max_size, sz);
80+
}
81+
return max_size;
82+
}
83+
};

0 commit comments

Comments
 (0)