๐๊ณต๋ถํ ๊ฑฐ List๐
- ํธ๋ฆฌ - 23. ์ฐ์ ์์ ํ์ ํ
- ํธ๋ฆฌ - 25. ์ํธ ๋ฐฐํ์ ์งํฉ(disjoint set)
์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์๋ฃ๊ฐ ๊ฐ์ฅ ๋จผ์ ๊บผ๋ด์ง๋ ํQueue
๊ท ํ ์กํ ์ด์ง ๊ฒ์ ํธ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์๋ค์ ์ฐ์ ์์๋ก ์ ๋ ฌํด๋๋ฉด ์ต๋ ์์๋ฅผ ์ฐพ์ ์ญ์ ํ๋ ์ผ๊ณผ ์์ ์ฝ์ ์ฐ์ฐ์ **O(NlgN)**๋์ ํ ์ ์๋ค.
ํ์ง๋ง, ๊ท ํ ์กํ ์ด์ง ๊ฒ์ ํธ๋ฆฌ๋ก ์ฐ์ ์์ ํ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๋๋ฌด๋ ๋ฌด๋ฆฌ...(์ฃผ๊ฐ์ ๋)
๊ทธ๋์ ๋ณด๋ค ๊ฐ๋จํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง **ํ(heap)**์ ์ฌ์ฉํ์ฌ ์ฐ์ ์์ ํ๋ฅผ ๊ตฌํํ๋ค.
how? ์ฐ์ ์์์ ์ค์ ์๋ฃ์ ์์ ๋ด๋ heap์ ๋ง๋ค๊ณ , ๋์์ฌ๊ณ๋ฅผ ๋น๊ตํ ๋๋ ์ฐ์ ์์๋ฅผ ๋น๊ตํ๋ฉด ๋๋ค.
โพ๏ธ (์ต๋)ํ์ ์ค์ํ ํน์ง
- ๋ถ๋ชจ ๋ ธ๋๊ฐ ๊ฐ์ง ์์๋ ํญ์ ์์ ๋ ธ๋๊ฐ ๊ฐ์ง ์์ ์ด์์ด๋ค. (=ํ์ ๋์ ๊ด๊ณ ๊ท์น)
- ํ์ ๋์ ๊ด๊ณ ๊ท์น์ ๋ฐ๋ผ ํธ๋ฆฌ์์ ๊ฐ์ฅ ํฐ ์์๋ ํญ์ ํธ๋ฆฌ์ ๋ฃจํธ์ ๋ค์ด๊ฐ๋ค.
- (๋ชจ์๊ท์น) ๋ง์ง๋ง ๋ ๋ฒจ์ ์ ์ธํ ๋ชจ๋ ๋ ๋ฒจ์ ๋ ธ๋๊ฐ ๊ฝ ์ฐจ ์๋ค.
- (๋ชจ์๊ท์น) ๋ง์ง๋ง ๋ ๋ฒจ์ ๋ ธ๋๊ฐ ์์ ๊ฒฝ์ฐ, ํญ์ ๊ฐ์ฅ ์ผ์ชฝ๋ถํฐ ์์๋๋ก ์ฑ์์ ธ ์๋ค.
- (ํน์ง 3 + ํน์ง 4 ๋ง์กฑ ์) ํ์ ๋์ด๋ **O(lgN)**์ด๋ค.
*ํธ๋ฆฌ์ ๋ ๋ฒจ = ๊น์ด๊ฐ ๊ฐ์ ๋ ธ๋๋ค์ ์งํฉ
|
์ผ์ฐจ์ ๋ฐฐ์ด A[]์ ๊ฐ ์์์ ํ์ ๋ ธ๋๋ค์ ์ผ๋์ผ ๋์ํ๋ฉด ๋ค์์ ๊ท์น์ ์ป๋๋ค.
- A[i]์ ๋์๋๋ ๋ ธ๋์ ์ผ์ชฝ ์์์ A[2*i + 1]
- A[i]์ ๋์๋๋ ๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์์ A[2*i + 2]
- A[i]์ ๋์๋๋ ๋ ธ๋์ ๋ถ๋ชจ๋ A[(i-1)/2]์ ๋์๋๋ค. (๋๋์ ๊ฒฐ๊ณผ๋ ๋ด๋ฆผ)
โจ๏ธ ์ ์๋ฅผ ์ ์ฅํ๋ ํ
vector<int> heap;
ํ์ ์์์ ๊ฐ์๋ ๋์ ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ ๋๋ค.
|
๋ชจ์ ๊ท์น์ ๋จผ์ ๋ง์กฑ์ํจ ํ, ๋์ ๊ด๊ณ ๊ท์น์ ๋ง์กฑ์ํจ๋ค.
์์ ์ฝ์ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ์ ๋ ธ๋๋ฅผ ํญ์ heap[] ๋ง์ง๋ง์ ์ถ๊ฐํ๋ค.
- ์ ์์๋ฅผ ์์ ์ ๋ถ๋ชจ ๋ ธ๋๊ฐ ๊ฐ์ง ์์์ ๋น๊ตํ๊ณ , ๋ถ๋ชจ ๋ ธ๋๊ฐ ๊ฐ์ง ์์๊ฐ ๋ ์์ผ๋ฉด ๋ ์์์ ์์น๋ฅผ ๋ฐ๊ฟ์ค๋ค.
- ์ ์์๊ฐ ๋ ํฌ๊ฑฐ๋ ๊ฐ์ ์์๋ฅผ ๊ฐ์ง ๋ถ๋ชจ ๋ ธ๋๋ฅผ ๋ง๋๊ฑฐ๋, ๋ฃจํธ์ ๋๋ฌํ ๋๊น์ง <๊ณผ์ 2>๋ฅผ ๋ฐ๋ณตํ๋ค.
โจ๏ธ ์ ์ ์์๋ฅผ ๊ฐ๋ ์ต๋ ํ์ ์ ์์ ์ฝ์ ํ๊ธฐ
/*
* ์ ์ ์์๋ฅผ ๋ด๋ ์ต๋ ํ heap์ ์ ์์ newValue๋ฅผ ์ฝ์
ํ๋ ํจ์
* @param heap [์ ์ ์์๋ฅผ ๋ด๋ ์ต๋ ํ]
* @param newValue [์ ์์]
*/
void push_heap(vector<int>& heap, int newValue) {
heap.push_back(newValue); //์ผ๋จ ๋ชจ์ ๊ท์น์ ๋ง์กฑ์ํค๊ธฐ ์ํด heap ๋งจ ๋์ ์์ ์ฝ์
int idx = heap.size() - 1; //์ด๊ธฐ ์ ์์์ ์์น
//idx>0 : ๋ฃจํธ์ ๋๋ฌํ๊ฑฐ๋
//heap[(idx-1)/2]<heap[idx] : ๋ถ๋ชจ๋
ธ๋๊ฐ์ด newValue๋ณด๋ค ์์ผ๋ฉด
while(idx>0 && heap[(idx-1)/2]<heap[idx]) {
swap(heap[idx], heap[(idx-1)/2]); //๋ ๋
ธ๋๋ฅผ ๋ฐ๊พผ๋ค
idx = (idx-1)/2; //newValue์ ์์น๋ฅผ ์์
}
}
โฑTime-Complexityโฑ
O(lgN)
|
โพ๏ธ ๋ชจ์ ๊ท์น ๋ง์กฑ ๊ณผ์
- ํ์ ๋ง์ง๋ง ๋ ธ๋๋ฅผ ์ง์ด๋ค.
- ๋ง์ง๋ง ๋ ธ๋์ ์๋ ์์๋ฅผ ๋ฃจํธ์ ๋ฎ์ด์์ด๋ค.
โพ๏ธ ๋์ ๊ด๊ณ ๊ท์น ๋ง์กฑ ๊ณผ์
- ํธ๋ฆฌ์ ๋ฐ๋ฅ์ ๋๋ฌํ๊ฑฐ๋, ๋ ์์์ด ๋ชจ๋ ๋ถ๋ชจ๋ ธ๋์ดํ์ ์์๋ฅผ ๊ฐ๊ณ ์์ ๋๊น์ง <๊ณผ์ 2> ๋ฐ๋ณต
- ๋ ์์์ด ๊ฐ์ง๊ณ ์๋ ์์ ์ค ํฐ ๋ ธ๋๋ฅผ ๋ถ๋ชจ๋ ธ๋์ ๋ฐ๊ฟ์ค๋ค.
โจ๏ธ ์ ์ ์์๋ฅผ ๊ฐ๋ ์ต๋ ํ์์ ์ต๋ ์์ ์ญ์ ํ๊ธฐ
/*
* ์ ์๋ฅผ ๋ด๋ ์ต๋ ํ heap์์ heap[0]์ ์ ๊ฑฐํ๋ค.
* @param heap [์ ์๋ฅผ ๋ด๋ ์ต๋ ํ]
*/
void pop_heap(vector<int>& heap) {
heap[0] = heap.back(); //ํ์ ๋ฃจํธ์ ๋ง์ง๋ง ๊ฐ์ ๋ฃ๋๋ค.
heap.pop_back(); //๋ง์ง๋ง ๋
ธ๋๋ ์ญ์
int here = 0; //๋ง์ง๋ง ๊ฐ์ ํ์ฌ ์์น
while(true) {
int left = here*2 + 1, right = here*2 + 2;//left:์ผ์ชฝ ์์๋
ธ๋, right:์ค๋ฅธ์ชฝ ์์๋
ธ๋
if(left >= heap.size()) break; //๋ฆฌํ์ ๋๋ฌํ ๊ฒฝ์ฐ ์ค๋จ
int next = here; //ํ์ฌ ์์น๋ฅผ next์ ์ ์ฅํด๋๊ณ
if(heap[next] < heap[left]) //ํ์ฌ๋
ธ๋(๋ถ๋ชจ)๋ณด๋ค ์ผ์ชฝ์์๋
ธ๋ ๊ฐ์ด ๋ ํฌ๋ฉด
next = left; //ํ์ฌ๋
ธ๋์์น๋ฅผ ์ผ์ชฝ์์๋
ธ๋ ์์น๋ก ์ค์
if(right < heap.size() && heap[next] < heap[right]) //ํ์ฌ๋
ธ๋(๋ถ๋ชจ)๋ณด๋ค ์ค๋ฅธ์ชฝ์์๋
ธ๋ ๊ฐ์ด ๋ ํฌ๋ฉด
next = right; //ํ์ฌ๋
ธ๋์์น๋ฅผ ์ค๋ฅธ์ชฝ์์๋
ธ๋ ์์น๋ก ์ค์
if(next == here) break; //๋ถ๋ชจ๋
ธ๋์ ๊ฐ์ด ์์๋
ธ๋ ๊ฐ๋ณด๋ค ํฌ๋ค๋ฉด(=๋์๊ด๊ณ๊ท์น์ ๋ง์กฑํ๋ค๋ฉด) while๋ฌธ ์ค๋จ
swap(heap[here], heap[next]); //์๋๋ผ๋ฉด ๋
ธ๋๋ฅผ ์๋ก ๋ฐ๊ฟ์ค๋ค
here = next; //ํ์ฌ ์์น ๊ฐฑ์
}
}
โฑTime-Complexityโฑ
O(lgN)
|
๋ฌธ์ : ํ ๋น ์์ด์์ ์์ํด์ ๊ฐ ์๊ฐ ์ถ๊ฐ๋ ๋๋ง๋ค ์ค๊ฐ ๊ฐ์ ๊ณ์ฐํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑ.
์์ด์ ๊ธธ์ด๊ฐ ์ง์์ผ ๋๋ ๊ฐ์ด๋ฐ ์๋ ๋ ๊ฐ ์ค ๋ณด๋ค ์์ ๊ฒ์ ์์ด์ ์ค๊ฐ ๊ฐ์ด๋ผ๊ณ ์ ์ํ๋ค.
โก๏ธkeypointโก๏ธ
-
ํธ๋ฆฝ์ ์ด์ฉํด ํด๊ฒฐํ๊ธฐ
-
์ฃผ์ด์ง ์์ด์ ์ซ์๋ค์ ์ ๋ ฌํ ๋ค, ์์ ์ ๋ฐ์ ์ต๋ํ์, ๋ค์ ์ ๋ฐ์ ์ต์ํ์ ๋ฃ์ด ํผ๋ค. ์ด ๊ฒฝ์ฐ ๋ค์์ ๋ถ๋ณ์์ผ๋ก ํํํ ์ ์๋ค.
- ์ต๋ ํ์ ํฌ๊ธฐ๋ ์ต์ ํ์ ํฌ๊ธฐ์ ๊ฐ๊ฑฐ๋, ํ๋ ๋ ํฌ๋ค.
- ์ต๋ ํ์ ์ต๋ ์์๋ ์ต์ ํ์ ์ต์ ์์๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค.
๊ทธ ๊ฒฐ๊ณผ, ์ด ์์ด์ ์ค๊ฐ ๊ฐ์ ํญ์ ์ต๋ ํ์ ๋ฃจํธ์ ์๊ฒ ๋๋ค.
๐**ํด๋ต(์ฝ๋)**๐
/*
* ๋ณํํ๋ ์ค๊ฐ ๊ฐ ๋ฌธ์ ์ ์
๋ ฅ ์์ฑํ๊ธฐ
*/
struct RNG {
int seed, a, b;
RNG(int _a, int _b) : a(_a), b(_b), seed(1983) {}
int next() {
int ret = seed;
seed = ((seed * (long long)a) + b) % 20090711;
return ret;
}
};
/*
* <iostream>, <queue>, <vector>
* ํ์ ์ด์ฉํด ๋ณํํ๋ ์ค๊ฐ ๊ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํจ์์ ๊ตฌํ
* @param n []
* @param rng []
*/
int runningMedian(int n, RNG rng) {
priority_queue<int, vector<int>, less<int>> maxHeap;
priority_queue<int, vector<int>, greater<int>> minHeap;
int ret = 0;
for(int cnt=1; cnt<=n; ++cnt) {
if(maxHeap.size() == minHeap.size()) maxHeap.push(rng.next());
else minHeap.push(rng.next());
if(!minHeap.empty() && !maxHeap.empty() && minHeap.top()<maxHeap.top()) {
int a = maxHeap.top();
int b = minHeap.top();
maxHeap.pop(); minHeap.pop();
maxHeap.push(b);
minHeap.push(a);
}
ret = (ret + maxHeap.top()) % 20090711;
}
return ret;
}
โฑTime-Complexityโฑ
O(lgN)
์ ๋์จ-ํ์ธํธ(Union-Find)
Union-Find ์๋ฃ๊ตฌ์กฐ๋?
๐ ๊ณตํต ์์๊ฐ ์๋, ๋ค์ ๋งํด ์ํธ ๋ฐฐํ์ ์ธ ๋ถ๋ถ ์งํฉ๋ค๋ก ๋๋ ์ง ์์๋ค์ ๋ํ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์กฐ์ํ๋ ์๋ฃ๊ตฌ์กฐ
n๊ฐ์ ์์๋ค๋ก ์ด๋ค์ง ์งํฉ์ ํํํ๊ธฐ ์ํด์, ์์๋ฅผ 0๋ถํฐ n-1๊น์ง๋ก ํํํ๊ณ ๊ฐ 1๊ฐ์ ์์๋ฅผ ํฌํจํ๋ n๊ฐ์ ์งํฉ์ ๋ง๋ ๋ค.
Union-Find์์ ์ฌ์ฉ๋๋ ์ธ ๊ฐ์ง ์ฐ์ฐ
์ด๊ธฐํ
: n๊ฐ์ ์์๊ฐ ๊ฐ๊ฐ์ ์งํฉ์ ํฌํจ๋์ด ์๋๋ก ์ด๊ธฐํunion
: ๋ ์์ a,b๊ฐ ์ฃผ์ด์ง ๋ ์ด๋ค์ด ์ํ ๋ ์งํฉ์ ํ๋๋ก ํฉ์น๋ค.find
: ์ด๋ค ์์ a๊ฐ ์ฃผ์ด์ง ๋, ์ด ์์๊ฐ ์ํ ์งํฉ์ ๋ฐํํ๋ค.
belongsTo[i]
: i๋ฒ ์์๊ฐ ์ํ๋ ์งํฉ์ ๋ฒํธ
์ด๊ธฐํ : belongsTo[i] = i
๐ต**๋ฐฐ์ด๋ก ์ํธ ๋ฐฐํ์ ์งํฉ ํํํ๊ธฐ์ ๋ฌธ์ ์ **
Union์ฐ์ฐ์ ํ ๋, belongTo์ ์์์ํ์ O(n)์๊ฐ์ด ์์๋๋ค.
ํ ์งํฉ์ ์ํ๋ ์์๋ค์ ํ๋์ ํธ๋ฆฌ๋ก ๋ฌถ์ด์ฃผ์ด, ์ํธ ๋ฐฐํ์ ์งํฉ ์๋ฃ๊ตฌ์กฐ๋ฅผ ํธ๋ฆฌ๋ค์ ์งํฉ์ผ๋ก ํํํ๋ ๊ฒ์ ์๋ฏธ.
๋ ์์๊ฐ ๊ฐ์ ์งํฉ์ ์๋์ง ํ์ธํ๋ ๋ฐฉ๋ฒ : ์ํ ํธ๋ฆฌ์ ๋ฃจํธ๊ฐ ๊ฐ์์ง ํ์ธํ๋ฉด ๋๋ค.
์ ์ฒด ์ฝ๋
struct NaiveDisjointSet {
vector<int> parent;
NaiveDisjointSet(int n) : parent(n) { //์๋ ๋ณต์ฌ ์์ฑ์ ์ค๋ช
์ฐธ๊ณ
for(int i=0; i<n; ++i) parent[i] = i;
}
//์ฐพ๊ธฐ ์ฐ์ฐ:find
int find(int u) const {
if(u == parent[u]) return u;
return find(parent[u]);
}
//ํฉ์น๊ธฐ ์ฐ์ฐ:union
void merge(int u, int v) {
u.find(u);
v.find(v);
if(u==v) return;
parent[u] = v;
}
};
๐ฉ๐C++::default copy constructor_๋ํดํธ ๋ณต์ฌ ์์ฑ์
#include <iostream>
#include <vector>
using namespace std;
class Sample {
vector<int> num;
int n = num.size();
public :
Sample(int param) : num(param) {
for(int i=0; i<n; ++i) num[i] = i;
}
void printNum() {
for(int i=0; i<n; ++i) cout<<num[i]<<endl;
}
};
int main()
{
vector<int> a = {1,2,3};
Sample first(3);
Sample num = first;
num.printNum();
return 0;
}
์คํ๊ฒฐ๊ณผ : 0 1 2
-
find ์ฐ์ฐ
-
์์๊ฐ ์ํ ํธ๋ฆฌ์ ๋ฃจํธ๋ฅผ ์ฐพ๋๋ค.
-
๋ชจ๋ ์์ ๋ ธ๋๊ฐ ๋ถ๋ชจ ๋ ธ๋์ ๋ํ ํฌ์ธํฐ๋ฅผ ๊ฐ์ง๊ณ ์์ด์ผ ํ๋ค.
-
โฑTime-Complexityโฑ : ํด๋น ํธ๋ฆฌ์ ๋์ด์ ๋น๋กํ๋ ์๊ฐ์ด ์์๋๋ค.
-
int find(int u) const { if(u == parent[u]) return u; return find(parent[u]); }
-
-
union ์ฐ์ฐ
-
๊ฐ ํธ๋ฆฌ์ ๋ฃจํธ๋ฅผ ์ฐพ๊ณ , ํ๋๋ฅผ ๋ค๋ฅธ ํ์ชฝ์ ์์์ผ๋ก ํฌํจ์ํค๋ฉด ๋๋ค.
-
โฑTime-Complexityโฑ : ํด๋น ํธ๋ฆฌ์ ๋์ด์ ๋น๋กํ๋ ์๊ฐ์ด ์์๋๋ค.
-
void merge(int u, int v) { u.find(u); v.find(v); if(u==v) return; parent[u] = v; }
-
ํธ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ์ํธ ๋ฐฐํ์ ์งํฉ์ ํํํ ๊ฒฝ์ฐ ์๊ธฐ๋ ๋ฌธ์ ์
๐ ์ฐ์ฐ์ ์์์ ๋ฐ๋ผ ์์นซ ํธ๋ฆฌ๊ฐ ํ์ชฝ์ผ๋ก ๊ธฐ์ธ์ด์ง ์ ์๋ค.
ํด๊ฒฐ๋ฐฉ์
๐ ๋ญํฌ(rank)์ ์ํ ํฉ์น๊ธฐ(union-by-rank) ์ต์ ํ : ๋ ํธ๋ฆฌ๋ฅผ ํฉ์น ๋, ํญ์ ๋์ด๊ฐ ๋ ๋ฎ์ ํธ๋ฆฌ๋ฅผ ๋ ๋์ ํธ๋ฆฌ ๋ฐ์ ์ง์ด๋ฃ์์ผ๋ก์จ ํธ๋ฆฌ์ ๋์ด๊ฐ ๋์์ง๋ ์ํฉ์ ๋ฐฉ์งํ๋ค.