๐ฆ 2. Data Structures
01. ํด์ํ ์ด๋ธ
ํด์ํ ์ด๋ธ(hash table)์ ํจ์จ์ ์ธ ํ์์ ์ํ ์๋ฃ๊ตฌ์กฐ๋ก์ ํค(key)๋ฅผ ๊ฐ(value)์ ๋์์ํจ๋ค.
๊ฐ๋จํ ํด์ํ ์ด๋ธ์ ์ฐ๊ฒฐ๋ฆฌ์คํธ(linked list)์ ํด์ ์ฝ๋ ํจ์(hash code function)๋ง ์์ผ๋ฉด ๋๋ค.
ํค์ ๊ฐ์ ํด์ํ ์ด๋ธ์ ๋ฃ์ ๋๋ ๋ค์ ๊ณผ์ ์ ๊ฑฐ์น๋ค.
- ํค์ ํด์ ์ฝ๋๋ฅผ ๊ณ์ฐํ๋ค. (ํค์ ๊ฐ์๋ ๋ฌดํํ์ง๋ง int ์ ๊ฐ์๋ ์ ํํ๊ธฐ ๋๋ฌธ์ ์๋ก ๋ค๋ฅธ ๋ ํค๊ฐ ๊ฐ์ ํด์ ์ฝ๋๋ฅผ ๊ฐ๋ฆฌํฌ ์๋ ์๋ค :: ์ถฉ๋)
hash(key) % array_length
์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ํด์ ์ฝ๋๋ฅผ ์ด์ฉํด ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ฅผ ๊ตฌํ๋ค.- ๋ฐฐ์ด์ ๊ฐ ์ธ๋ฑ์ค์๋ ํค์ ๊ฐ์ผ๋ก ์ด๋ฃจ์ด์ง ์ฐ๊ฒฐ๋ฆฌ์คํธ๊ฐ ์กด์ฌํ๋ค. ํค์ ๊ฐ์ ํด๋น ์ธ๋ฑ์ค์ ์ ์ฅํ๋ค. ์ถฉ๋์ ๋๋นํ์ฌ ๋ฐ๋์ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ์ด์ฉํด์ผ ํ๋ค.
์ํ ์๊ฐ
- ์ต์
์ ๊ฒฝ์ฐ : ์ถฉ๋์ด ์์ฃผ ๋ฐ์ํ๋ค๋ฉด
O(N)
- ์ต์ ์ ๊ฒฝ์ฐ : ์ถฉ๋์ ์ต์ํ ํ๋ค๋ฉด
O(1)
- ๊ท ํ ์ด์ง ํ์ ํธ๋ฆฌ์ผ ๊ฒฝ์ฐ :
O(logN)
ArrayList ์ ๊ฐ๋ณ ํฌ๊ธฐ ๋ฐฐ์ด
ํน์ ์ธ์ด์์๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ์๋์ผ๋ก ์กฐ์ ํ ์ ์์ง๋ง, ์๋ฐ ๊ฐ์ ์ธ์ด์์๋ ๋ฐฐ์ด์ ๊ธธ์ด๊ฐ ๊ณ ์ ๋์ด ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ ๋ฐฐ์ด์ ๋ง๋ค ๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ํจ๊ป ์ง์ ํด์ผ ํ๋ค.
๋์ ๊ฐ๋ณ ํฌ๊ธฐ ๊ธฐ๋ฅ์ด ๋ด์ฌ๋์ด ์๋ ๋ฐฐ์ด๊ณผ ๋น์ทํ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ํ ๋ ๋ณดํต ArrayList ๋ฅผ ์ฌ์ฉํ๋ค.
ArrayList๋ ํ์์ ๋ฐ๋ผ ํฌ๊ธฐ๋ฅผ ๋ณํ์ํค๋ฉด์๋ O(1)
์ ์ ๊ทผ ์๊ฐ์ ์ ์งํ๋ค.
๋ฐฐ์ด์ด ๊ฐ๋ ์ฐจ๋ ์๊ฐ, ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ ๋ฐฐ ๋๋ฆฌ๋๋ฐ, ์ด ๋ ์๊ฐ์ O(N)
์ด๋ค.
ํ์ง๋ง ์์ฃผ ๋ฐ์ํ๋ ์ผ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ํ ์
๋ ฅ ์๊ฐ์ผ๋ก ๊ณ์ฐํ๋ฉด ์ฌ์ ํ O(1)
์ ์ ์งํ๋ค.
์ํ ์ ๋ ฅ ์๊ฐ์ ์ O(1)์ด ๋๋๊ฐ.
๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ K๋ก ๋๋ฆฌ๋ฉด ๊ทธ ์ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ K์ ์ ๋ฐ์ด์์ ๊ฒ์ด๋ฏ๋ก K/2 ๋งํผ์ ์์๋ฅผ ๋ณต์ฌํด์ผ ํ๋ค.
ํฌ๊ธฐ๊ฐ N์ธ ๋ฐฐ์ด์์ N๊ฐ์ ์์๋ฅผ ์ฝ์ ํ๊ธฐ ์ํด ๋ณต์ฌํด์ผ ํ๋ ์์์ ์ด ๊ฐ์๋
N/2 + N/4 + N/8 + ... + 2 + 1
๋ก N๋ณด๋ค ์๋ค.
๋ฐ๋ผ์ N๊ฐ์ ์์๋ฅผ ์ฝ์
ํ ๋ ์์๋๋ ์์
์ O(N)
์ด ๋๋ค.
ํ๊ท ์ ์ผ๋ก ๊ฐ ์ฝ์
์ O(1)
์ด ์์๋๋ค๊ณ ํ ์ ์๋ค.
StringBuilder
๋ฌธ์์ด์ ๋ฆฌ์คํธ๊ฐ ์ฃผ์ด์ก์ ๋ ์ด ๋ฌธ์์ด๋ค์ ํ๋๋ก ์ด์ด ๋ถ์ด๋ ค๊ณ ํ๋ค. ์ด ๋์ ์ํ์๊ฐ์?
1
2
3
4
5
6
7
String joinWords(String[] words) {
String sentence = "";
for (String w : words) {
sentence = sentence + w;
}
return sentence;
}
๋ฌธ์์ด์ ์ด์ด๋ถ์ผ ๋ ๋ง๋ค 2๊ฐ์ ๋ฌธ์์ด์ ์ฝ์ด ๋ค์ธ ๋ค ๋ฌธ์๋ฅผ ํ๋ํ๋ ์๋ก์ด ๋ฌธ์์ด์ ๋ณต์ฌํด์ผ ํ๋ค.
์ฒ์์๋ x๊ฐ, 2๋ฒ์งธ๋ 2x๊ฐ, 3๋ฒ์งธ๋ 3x๊ฐ โฆ n๋ฒ์งธ๋ nx๊ฐ ๋ณต์ฌํด์ผ ํ๋ค.
๋ฐ๋ผ์ ์ด ์ํ์๊ฐ์ O(x + 2x + ... + nx) = O(xn^2)
๊ฐ ๋๋ค.
StringBuilder ๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค. StringBuilder ๋ ๋จ์ํ๊ฒ ๊ฐ๋ณ ํฌ๊ธฐ ๋ฐฐ์ด์ ์ด์ฉํด์ ํ์ํ ๊ฒฝ์ฐ์๋ง ๋ฌธ์์ด์ ๋ณต์ฌํ๊ฒ๋ ํ ์ ์๋ค.
1
2
3
4
5
6
7
String joinWords(String[] words) {
StringBuilder sentence = new StringBuilder();
for (String w : words) {
sentence.append(w);
}
return sentence.toString();
}
02. ์ฐ๊ฒฐ๋ฆฌ์คํธ
์ฐ๊ฒฐ๋ฆฌ์คํธ๋ ์ฐจ๋ก๋ก ์ฐ๊ฒฐ๋ ๋ ธ๋๋ฅผ ํํํด์ฃผ๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
๋จ๋ฐฉํฅ ์ฐ๊ฒฐ๋ฆฌ์คํธ์์ ๊ฐ ๋ ธ๋๋ ๋ค์ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
์๋ฐฉํฅ ์ฐ๊ฒฐ๋ฆฌ์คํธ์์ ๊ฐ ๋ ธ๋๋ ๋ค์ ๋ ธ๋์ ์ด์ ๋ ธ๋๋ฅผ ํจ๊ป ๊ฐ๋ฆฌํจ๋ค.
๋ฐฐ์ด๊ณผ๋ ๋ฌ๋ฆฌ ์ฐ๊ฒฐ๋ฆฌ์คํธ์์๋ ํน์ ์ธ๋ฑ์ค๋ฅผ ์์ ์๊ฐ์ ์ ๊ทผํ ์ ์๋ค.
๋ฆฌ์คํธ์์ K๋ฒ์งธ ์์๋ฅผ ์ฐพ๊ณ ์ถ๋ค๋ฉด K๋ฒ ๋ฃจํ๋ฅผ ๋์์ผํ๋ค.
๋ค๋ง ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ์ฅ์ ์ ๋ฆฌ์คํธ์ ์์ ์ง์ ์์ ์์ดํ ์ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ๋ ์ฐ์ฐ์ ์์ ์๊ฐ์ ํ ์ ์๋ค.
์ฐ๊ฒฐ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ๊ตฌํํ ์ฝ๋์ด๋ค
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Node {
Node next = null;
int data;
public Node(int d) {
data = d;
}
void appendToTail(int d) {
Node end = new Node(d);
Node n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
}
}
์ฐ๊ฒฐ๋ฆฌ์คํธ์ ์ ๊ทผํ ๋ head ๋ ธ๋์ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
์ด๋ฐ ์์ผ๋ก ๊ตฌํํ ๋ ์กฐ์ฌํด์ผ ํ๋ ๋ถ๋ถ์ด ์๋ค.
์ฌ๋ฌ ๊ฐ์ฒด๋ค์ด ๋์์ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ์ฐธ์กฐํ๋ ๋์ค์ head ๊ฐ ๋ฐ๋๋ฉด?
head ๊ฐ ๋ฐ๋์์์๋ ์ด๋ค ๊ฐ์ฒด๋ ์ด์ head ๋ฅผ ๊ณ์ ๊ฐ๋ฆฌํฌ์๋ ์๋ค.
ํ ์ ์๋ค๋ฉด Node ํด๋์ค๋ฅผ ํฌํจํ๋ LinkedList ํด๋์ค๋ฅผ ๋ง๋๋๊ฒ ์ข๋ค.
ํด๋์ค ์์ head Node ๋ณ์๋ฅผ ๋จ ํ๋๋ง ์ ์ํด ๋์์ผ๋ก์จ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
Runner ๊ธฐ๋ฒ
Runner (๋ถ๊ฐ ํฌ์ธํฐ)๋ ์ฐ๊ฒฐ๋ฆฌ์คํธ ๋ฌธ์ ์์ ๋ง์ด ํ์ฉ๋๋ ๊ธฐ๋ฒ์ด๋ค.
์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ์ํํ ๋ ๋ ๊ฐ์ ํฌ์ธํฐ๋ฅผ ๋์์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
์ด ๋, ํ ํฌ์ธํฐ๋ ๋ค๋ฅธ ํฌ์ธํฐ๋ณด๋ค ์์๋๋ก ํ๋ค.
์๋ฅผ ๋ค์ด
1
A1 -> A2 -> ... -> An -> B1 -> B2 -> ... -> Bn
์ด ๋ฆฌ์คํธ๋ฅผ ๋ค์์ฒ๋ผ ์ ๋ ฌํ๊ณ ์ ํ๋ค.
1
A1 -> B1 -> A2 -> B2 -> ... -> An -> Bn
์์ ํฌ์ธํฐ P1 ์ ๋๊ณ ๋ฐ๋ผ์ค๋ ํฌ์ธํฐ P2๊ฐ ํ ๋ฒ ์์ง์ผ ๋๋ง๋ค ํฌ์ธํฐ P1์ด ๋ ๋ฒ ์์ง์ด๋๋ก ์ค์ ํ์.
๊ทธ๋ฌ๋ฉด P1 ์ด ์ฐ๊ฒฐ๋ฆฌ์คํธ ๋์ ๋๋ฌํ๋ฉด P2๋ ๊ฐ์ด๋ฐ ์ง์ ์ ์๊ฒ ๋๋ค.
์ด ์ํ์์ P1์ ๋ค์ ๋งจ ์์ผ๋ก ์ฎ๊ธฐ๊ณ P2๋ก ํ์ฌ๊ธ ์์๋ฅผ ์ฌ๋ฐฐ์ดํ๋๋ก ํ ์ ์๋ค.
์ฆ, ๋ฃจํ๊ฐ ์คํ๋ ๋๋ง๋ค P2๊ฐ ๊ฐ๋ฆฌํค๋ ์์๋ฅผ P1 ๋ค๋ก ์ฎ๊ธฐ๋ ๊ฒ์ด๋ค.
์ฌ๊ท ๋ฌธ์
์ฐ๊ฒฐ๋ฆฌ์คํธ ๊ด๋ จ ๋ฌธ์ ๊ฐ์ด๋ฐ ์๋น์๋ ์ฌ๊ท ํธ์ถ์ ์์กดํ๋ค.
์ฌ๊ท ํธ์ถ ๊น์ด๊ฐ n์ด ๋ ๊ฒฝ์ฐ ํด๋น ์ฌ๊ท ์๊ณ ๋ฆฌ์ฆ์ด ์ ์ด๋ O(n)
๋งํผ์ ๊ณต๊ฐ์ ์ฌ์ฉํ๋ค๋ ์ฌ์ค์ ๊ธฐ์ตํ๋ผ.
03. ์คํ๊ณผ ํ
์คํ ์๋ฃ๊ตฌ์กฐ๋ ๋ฐ์ดํฐ๋ฅผ ์์ ์ฌ๋ฆฐ๋ค๋ ์๋ฏธ์ด๋ค.
๋๋ก๋ ๋ฐฐ์ด๋ณด๋ค ์คํ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๊ฒ์ด ๋ ์ ํฉํ ๋ฐฉ๋ฒ์ผ ์ ์๋ค.
์คํ์ LIFO(Last-In-First-Out)์ ๋ฐ๋ผ ์๋ฃ๋ฅผ ๋ฐฐ์ดํ๋ค.
๊ฐ์ฅ ์ต๊ทผ์ ์คํ์ ์ถ๊ฐํ ํญ๋ชฉ์ด ๊ฐ์ฅ ๋จผ์ ์ ๊ฑฐ๋๋ค.
์คํ์ ์ฐ์ฐ์ ๋ค์๊ณผ ๊ฐ๋ค.
- pop(): ๊ฐ์ฅ ์์ ํญ๋ชฉ์ ์ ๊ฑฐํ๋ค.
- push(item) : ์์ดํ ํ๋๋ฅผ ์คํ ๊ฐ์ฅ ์ ๋ถ๋ถ์ ์ถ๊ฐํ๋ค.
- peek() : ๊ฐ์ฅ ์์ ํญ๋ชฉ์ ๋ฐํํ๋ค.
- isEmpty() : ๋น์ด์์ผ๋ฉด true๋ฅผ ๋ฐํํ๋ค.
๋ฐฐ์ด๊ณผ ๋ฌ๋ฆฌ ์คํ์ ์์ ์๊ฐ์ i๋ฒ์งธ ํญ๋ชฉ์ ์ ๊ทผํ ์ ์๋ค.
ํ์ง๋ง ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ๋ ์ฐ์ฐ์ ์์ ์๊ฐ์ ๊ฐ๋ฅํ๋ค.
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
32
public class MyStack {
private static class StackNode {
private T data;
private StackNode Next;
private StackNode(T data) {
this.data = data;
}
}
private StackNode top;
public T pop() {
if (top == null) throw new EmptyStackException();
T item = top.data;
top = top.next;
return item;
}
public void push(T item) {
StackNode t = new StackNode(item);
t.next = top;
top = t;
}
public T peek() {
if (top == null) throw new EmptyStackException();
return top.data;
}
public boolean isEmpty() {
return top == null;
}
}
์คํ์ ์ฌ๊ท ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ ๋ ์ ์ฉํ๋ค.
์ฌ๊ท์ ์ผ๋ก ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋ ๊ฒฝ์ฐ ์์ ๋ฐ์ดํฐ๋ฅผ ์คํ์ ๋ฃ์ด์ฃผ๊ณ , ์ฌ๊ท ํจ์๋ฅผ ๋น ์ ธ ๋์ ํด๊ฐ ๊ฒ์(backtrack)์ ํ ๋ ์คํ์ ๋ฃ์ด ๋์๋ ์์ ๋ฐ์ดํฐ๋ฅผ ๋นผ์ค๋ค.
์คํ์ ์ด๋ฐ ์ผ๋ จ์ ํ์๋ฅผ ์ง๊ด์ ์ผ๋ก ๊ฐ๋ฅํ๊ฒ ํด์ค๋ค.
์คํ์ ๋ํ ์ฌ๊ท ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๋ณต์ ํํ(iterative)๋ฅผ ํตํด ๊ตฌํํ ์ ์๊ฒ ํด์ค๋ค.
ํ ๊ตฌํํ๊ธฐ
ํ๋ FIFO(First-In-First-Out) ์์๋ฅผ ๋ฐ๋ฅธ๋ค.
ํ์ ์ฐ์ฐ์ ๋ค์๊ณผ ๊ฐ๋ค.
- add(item) : ์์ดํ ํ๋๋ฅผ ๋ฆฌ์คํธ์ ๋ ๋ถ๋ถ์ ์ถ๊ฐํ๋ค.
- remove() : ๋ฆฌ์คํธ์ ์ฒซ ๋ฒ์งธ ํญ๋ชฉ์ ์ ๊ฑฐํ๋ค.
- peek() : ๊ฐ์ฅ ์์ ํญ๋ชฉ์ ๋ฐํํ๋ค.
- isEmpty() : ๋น์ด์์ผ๋ฉด true๋ฅผ ๋ฐํํ๋ค.
์ฐ๊ฒฐ๋ฆฌ์คํธ์ ๋ฐ๋ ๋ฐฉํฅ์์ ํญ๋ชฉ์ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ๋๋ก ๊ตฌํํ๋ค๋ฉด ๊ทผ๋ณธ์ ์ผ๋ก ํ์ ๊ฐ๋ค.
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
32
33
34
35
36
37
38
39
40
41
public class MyQueue {
private static class QueueNode {
private T data;
private QueueNode Next;
private QueueNode (T data) {
this.data = data;
}
}
private QueueNode first;
private QueueNode last;
public void add(T item) {
QueueNode t = new QueueNode(item);
if (lst != null) {
last.next = t;
}
last = t;
if (first == null) {
first = last;
}
}
public T remove() {
if (first == null) throw new NoSuchElementException();
T data = first.data;
first = first.next;
if (first == null) {
last = null;
}
return data;
}
public T peek() {
if (first == null) throw new NoSuchElementException();
return first.data;
}
public boolean isEmpty() {
return first == null;
}
}
ํ์์ ์ฒ์๊ณผ ๋ง์ง๋ง ๋ ธ๋๋ฅผ ๊ฐฑ์ ํ ๋ ์ค์๊ฐ ๋์ค๊ธฐ ์ฝ๋ค.
ํ๋ ๋๋น ์ฐ์ ํ์๊ณผ ์บ์๋ฅผ ๊ตฌํํ๋ ๊ฒฝ์ฐ์ ์ข ์ข ์ฌ์ฉ๋๋ค.