โ๏ธ ๋ด ์ฝ๋๊ฐ ๋๋ ธ๋ ์ด์ : LinkedList๋ฅผ ๋ฐฐ์ด๋ก ๋ฐ๊พธ๊ณ ์๊ธด ์ผ
๐ฃ ์์์ ์ฝ๋ ๋น๊ต์์
์ต๊ทผ์ ๋ฐฑ์ค 14002๋ฒ: ๊ฐ์ฅ ๊ธด ์ฆ๊ฐํ๋ ๋ถ๋ถ ์์ด 5 ๋ฌธ์ ๋ฅผ ํ๋ค๊ฐ,
๋ค๋ฅธ ์ฌ๋์ ํ์ด์ ๋ด ํ์ด ์ฌ์ด์์ ์๋ ์ฐจ์ด๊ฐ ์ ๋ ํฌ๊ฒ ๋๋ ๊ฑธ ๋ฐ๊ฒฌํ๋ค.
๋ก์ง์ ๊ฐ์๋ค.
LIS(Longest Increasing Subsequence) ๊ตฌํ๊ณ , ์ค์ ์์ด์ ์ญ์ถ์ ํด์ ์ถ๋ ฅํ๋ค.
๊ทธ๋ฐ๋ฐ ๋๋ ์ด๋ ๊ฒ ์ผ๋ค:
LinkedList<Integer> result = new LinkedList<>();
while (idx != -1) {
result.addFirst(arr[idx]);
idx = prev[idx];
}
๋ฐ๋ฉด, ๋ค๋ฅธ ์ฌ๋์ ์ฝ๋๋ ์ด๋ ๊ฒ ๋ฐฐ์ด๋ก ์ฒ๋ฆฌํ๊ณ ์์๋ค:
int[] result = new int[length];
int pos = length - 1;
while (idx != -1) {
result[pos--] = arr[idx];
idx = prev[idx];
}
๐ค ์ฝ๋ ์ฐจ์ด? ๋จ์ํ addFirst()๋, ๋ฐฐ์ด ์ธ๋ฑ์ค๋.
๊ทธ๋ฐ๋ฐ ์คํ ์๋๋… ์ฐจ์์ด ๋ฌ๋๋ค!
๐ ๊ถ๊ธ์ฆ: ์ ์ด๋ ๊ฒ ๋๋ฆฌ์ง?
์ฒ์์ ์์ํ๋ค.
LinkedList.addFirst()๋ O(1)์ธ๋ฐ? → ๊ทผ๋ฐ ์ ๋๋ฆด๊น?
๐ฆ ์๋ฃ๊ตฌ์กฐ ๊ด์ ์์ ๋ถ์ํด๋ณด์
1. ๐งฑ ๋ฐฐ์ด (Array)
- ์ฐ์๋ ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก์ ์ ์ฅ๋จ
- ํน์ ์ธ๋ฑ์ค๋ก์ ์ ๊ทผ์ด O(1)
- CPU ์บ์ ์ ์ค๋ฅ ์ด ๋์ → ์๋ ๋น ๋ฆ
๐ก ๊ณ ์๋๋ก์ฒ๋ผ ๋ฌ๋ฆผ. ๋ฐฐ์ด[1000000] ํด๋ ์ฆ์ ๋์ฐฉ.
2. ๐ LinkedList
- ๊ฐ ๋ ธ๋๋ ๊ฐ + ๋ค์ ๋ ธ๋ ์ฃผ์๋ฅผ ๊ฐ์ง
- ๋ฉ๋ชจ๋ฆฌ์์ ํฉ์ด์ ธ ์์ → ์ ๊ทผ ์ ์ฐธ์กฐ ๋ฐ๋ผ๊ฐ์ผ ํจ
- ํฌ์ธํฐ ์ฐ๊ฒฐ ๋๋ฌธ์ GC์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ๋ถํ ์์
๐ก ์ง์ง๋ง๋ค ๋ฐฉ๋ฌธํ๋ ํ๋ฐฐ์ฐจ ๋๋. ๋๋ฆผ.
3. ๐ฃ addFirst()์ ์ค์ฒด
result.addFirst(value); // O(1)
์ด๋ก ์ O(1)์ด์ง๋ง ํ์ค์ ๋ค๋ฆ.
- ๊ฐ์ฒด ์์ฑ (Node)
- ํฌ์ธํฐ ๋ณ๊ฒฝ
- ํ์ ํฉ์ด์ง ๊ตฌ์กฐ
- GC ํธ๋ํน ๋ถ๋ด
๐ฅ ๋ฐ๋ณต๋๋ฉด ์บ์๋ ์ ๋จน๊ณ , ์ฐธ์กฐ ๋ถํ๋ ์์ด๊ณ , ๊ฒฐ๊ตญ ๋๋ ค์ง.
โ ๏ธ ๋ฐ์ดํฐ๊ฐ ๋ง์์ง์๋ก ์ฐจ์ด๋ ๊ธฐํ๊ธ์์ ์ผ๋ก ์ปค์ง๋ค.
โ ๊ฒฐ๋ก : ๋ฐ์ดํฐ๊ฐ ๋ง์์ง๊ณ ๋ณ๊ฒฝ์ด ์๋ค๋ฉด ๋ฐฐ์ด์ด ํจ์ฌ ์ ๋ฆฌ
๋น๊ต ํญ๋ชฉ | Array | LinkedList |
๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ | ์ฐ์์ | ๋น์ฐ์ (ํฌ์ธํฐ ๊ธฐ๋ฐ) |
์ ๊ทผ ๋ฐฉ์ | ์ง์ ์ธ๋ฑ์ฑ (๋น ๋ฆ) | ์ฐธ์กฐ ๋ฐ๋ผ๊ฐ๊ธฐ (๋๋ฆผ) |
์บ์ ํจ์จ | ๋์ | ๋ฎ์ |
GC ์ํฅ | ์ ์ | ํผ |
๋์ฉ๋ ๋ฐ์ดํฐ | ๊ฐ๋ ฅ ์ถ์ฒ | ์ง์ |
๐งฉ ๊ทธ๋ ๋ค๋ฉด LinkedList๋ ์ธ์ ์ฐ๋ ๊ฒ ์ข์๊น?
์์์๋ LinkedList.addFirst() ๋๋ฌธ์ ์๊ธด ์ฑ๋ฅ ์ ํ๋ฅผ ์ฌ๋ก๋ก ๋ณด์ฌ์ฃผ๋ฉฐ,
LinkedList์ ๊ตฌ์กฐ์ ํ๊ณ์ ๋ํด ๋ค๋ค๋ค.
๊ทธ๋ ๋ค๊ณ ํด์ “LinkedList๋ ์ ๋ ์ฐ๋ฉด ์ ๋๋ ์๋ฃ๊ตฌ์กฐ์ผ!” ๋ผ๋ ๊ฑด ์๋๋ค.
LinkedList๋ ๋ถ๋ช ๋ฐฐ์ด๋ก๋ ํด๊ฒฐํ๊ธฐ ์ด๋ ค์ด ๋ฌธ์ ๋ค์ ํนํ๋์ด ์๋ค.
๐ LinkedList์ ๊ฐ์ ์?
1. ๐งท ์ค๊ฐ ์ฝ์ /์ญ์ ๊ฐ ์ฆ์ ๋
๋ฐฐ์ด์ ์ค๊ฐ ์์๋ฅผ ์ฝ์ ํ๊ฑฐ๋ ์ญ์ ํ ๋ ๋ชจ๋ ์์๋ฅผ ๋ค๋ก ๋ฐ๊ฑฐ๋ ๋น๊ฒจ์ผ ํ๋ค.
// ๋ฐฐ์ด์์ ์ธ๋ฑ์ค 2์ ์ฝ์
for (int i = size; i > 2; i--) {
arr[i] = arr[i - 1]; // ๋ค๋ก ๋ฐ๊ธฐ
}
→ O(N) ์๊ฐ ์์
→ ๋ฐ์ดํฐ ํฌ๊ณ ์ค๊ฐ ์์ ๋ง์ผ๋ฉด ์น๋ช ์
๐ ๋ฐ๋ฉด LinkedList๋ ๋ ธ๋ ๊ฐ ์ฐ๊ฒฐ๋ง ๋ฐ๊พธ๋ฉด ๋๋ฏ๋ก:
node.prev.next = newNode;
newNode.prev = node.prev;
newNode.next = node;
node.prev = newNode;
→ O(1) ์ฝ์ /์ญ์ ๊ฐ๋ฅ
→ ์ฆ, ์ค๊ฐ ์กฐ์์ด ๋ง์ ๋ ์ ๋ฆฌ
2. ๐ ๋ฐ์ดํฐ ํฌ๊ธฐ๊ฐ ์ ๋์ ์ผ ๋
๋ฐฐ์ด์ ๊ณ ์ ๋ ํฌ๊ธฐ๋ก ํ ๋น๋๊ธฐ ๋๋ฌธ์, ํฌ๊ธฐ ์กฐ์ ์ด ํ์ํ๋ฉด ๋ณต์ฌ ๋น์ฉ์ด ๋ฐ์ํจ.
int[] newArr = new int[arr.length * 2];
System.arraycopy(arr, 0, newArr, 0, arr.length);
๋ฐ๋ฉด, LinkedList๋ ์๋ก์ด ๋ ธ๋๋ฅผ ํ๋ํ๋ ์ถ๊ฐํ ์ ์์ผ๋ฏ๋ก ํฌ๊ธฐ ์กฐ์ ๋น์ฉ์ด ์์.
3. ๐ฏ ์ ํ ํ์ ๊ธฐ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์ ๋ฆฌํ ๋
- ์: ๊ตฌํ ๋ฌธ์ ์์ ๋ฑ(Deque) ํํ๋ก ์๋ค๋ก ์์๋ฅผ ์ถ๊ฐ/์ญ์ ํด์ผ ํ๋ ์ํฉ
- Queue, Deque, Stack ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ง์ ๊ตฌํํ ๋
Java์์ LinkedList๋ Deque ์ธํฐํ์ด์ค๋ ๊ตฌํํ๋ฏ๋ก, ์๋ฐฉํฅ ํ๋ก์ ์์ฃผ ์ ์ฉํจ:
Deque<Integer> deque = new LinkedList<>();
deque.addFirst(1);
deque.addLast(2);
deque.pollFirst(); // 1
deque.pollLast(); // 2
→ ๋ฐฐ์ด๋ก ๊ตฌํํ๋ ค๋ฉด ArrayDeque์ด ๋ ๋ซ์ง๋ง,
๊ธฐ๋ฅ ๊ตฌํ ํ ์คํธ๋, ์ธํฐํ์ด์ค ์ค์ฌ ์ฝ๋์์๋ LinkedList๋ ๊ฐ์ ์์
๐ ์ ๋ฆฌ: LinkedList vs Array
์ํฉ์ถ์ฒ ์๋ฃ๊ตฌ์กฐ
์์ ์ ๊ทผ์ด ๋ง๋ค (get(i)) | ๋ฐฐ์ด (Array) |
์ค๊ฐ ์ฝ์ /์ญ์ ๊ฐ ๋ง๋ค | LinkedList |
๋ฐ์ดํฐ ํฌ๊ธฐ๊ฐ ๊ณ์ ๋ณํ๋ค | LinkedList |
๋๋์ ์์ ์ฒ๋ฆฌ (์ฑ๋ฅ ์ค์) | ๋ฐฐ์ด |
์๋ค๋ก ์ถ๊ฐ/์ญ์ ๋ง ํ๋ค | ArrayDeque or LinkedList (์์ ๋ฐ์ดํฐ์ผ ๋๋ ํฐ ์ฐจ์ด ์์) |
โ ํ ์ค ์์ฝ
๋ฐฐ์ด์ ์ฝ๊ณ ์ธ ๋ ๋น ๋ฅด๊ณ , LinkedList๋ ์ค๊ฐ์์ ์ ์ฐํ๋ค.
์ํฉ์ ๋ฐ๋ผ ์ฐ๋ ์๋ฃ๊ตฌ์กฐ๋ ๋ฌ๋ผ์ ธ์ผ ํ๋ค.
๐ ๋ง๋ฌด๋ฆฌ
์ด๋ฒ ๊ฒฝํ์ ํตํด ํ๋ ๋ ํ์คํ ๋ฐฐ์ด ๊ฑด,
“์๋ฃ๊ตฌ์กฐ๋ ๋๊ตฌ๋ค. ๋๊ตฌ๋ ์ฉ๋์ ๋ง๊ฒ ์จ์ผ ์ง์ง ๊ฐ์ด ๋๋ค.” ๋ ์ ์ด๋ค.
LinkedList๋ ๋๋ฆด ์๋ ์์ง๋ง, ๋๋ก๋ ๋ฐฐ์ด๋ก๋ ๊ตฌํ์ด ๋ฒ๊ฑฐ๋ก์ด ๋ฌธ์ ๋ฅผ
๊ฐ๋จํ๊ฒ ํ ์ ์๊ฒ ํด์ฃผ๋ ๋๊ตฌ๋ค. ์ฑ๋ฅ๋ง ๋ณผ ๊ฒ ์๋๋ผ ๊ตฌํ์ ํธ์์ฑ, ์๊ตฌ๋๋ ๊ธฐ๋ฅ, ์ ์ฐ์ฑ๊น์ง ๊ณ ๋ คํด์
์ ์ ํ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ ํํ๋ ๊ฒ ์ง์ง ๊ฐ๋ฐ์์ ์ผ์ค๋ผ๊ณ ์๊ฐํ๋ค.