์๊ณ ๋ฆฌ์ฆ์ ์ฑ๋ฅ์ ์ฐ๊ตฌํ๋ ์ค ์ด๋ฐ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค.
์ด ๊ธ์ ์์์ ๋ํ ์ผ์ข
์ ๋ฐ์ฃผ์
๋๋ค. ์ฌ๊ธฐ์๋ ํ์๋ ๋ชจ๋ ์๋ฃจ์
์ ๋ํ ์ค๋ช
๊ณผ JavaScript๋ก ์์ฑ๋ ์๋ฃจ์
์ ์์ฒด ๋ฒ์ ์ด ์ ๊ณต๋ฉ๋๋ค. ๊ฐ ์๊ณ ๋ฆฌ์ฆ์ ๋ฏธ๋ฌํ ์ฐจ์ด๋ ๋
ผ์๋ฉ๋๋ค.
์๋ฆผ: "Habr"์ ๋ชจ๋ ๋ ์๋ฅผ ์ํ - "Habr" ํ๋ก๋ชจ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ Skillbox ๊ณผ์ ์ ๋ฑ๋กํ ๋ 10 ๋ฃจ๋ธ ํ ์ธ.
Skillbox๋ ๋ค์์ ๊ถ์ฅํฉ๋๋ค. ์ค๊ธฐ ์ฝ์ค
"๋ชจ๋ฐ์ผ ๊ฐ๋ฐ์ PRO" .
๋ฌธ์ ์ฑ๋ช
์์๊ฐ ์ง์ ๋ ๋ฐฐ์ด๊ณผ ํน์ ๊ฐ์ด ์ ๊ณต๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ฐฐ์ด์ ์๋ ๋ ์ซ์์ ํฉ์ด ์ฃผ์ด์ง ๊ฐ๊ณผ ๊ฐ์ ์ ์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ true ๋๋ false๋ฅผ ๋ฐํํ๋ ํจ์๋ฅผ ์์ฑํ๋ผ๋ ์์ฒญ์ ๋ฐ์ต๋๋ค.
์ฆ, ๋ฐฐ์ด์ ํจ๊ป ๋ํ๋ฉด ์ง์ ๋ ๊ฐ๊ณผ ๊ฐ์ ๋ ๊ฐ์ ์ ์ x์ y๊ฐ ์์ต๋๊น?
์์ A
๋ฐฐ์ด [1, 2, 4, 9]๊ฐ ์ฃผ์ด์ง๊ณ ๊ฐ์ด 8์ธ ๊ฒฝ์ฐ ๋ฐฐ์ด์ ์๋ ๋ ์ซ์์ ํฉ์ด 8์ด ๋ ์ ์๊ธฐ ๋๋ฌธ์ ํจ์๋ false๋ฅผ ๋ฐํํฉ๋๋ค.
์์ B
๊ทธ๋ฌ๋ ๋ฐฐ์ด [1, 2, 4, 4]์ด๊ณ ๊ฐ์ด 8์ธ ๊ฒฝ์ฐ 4 + 4 = 8์ด๋ฏ๋ก ํจ์๋ true๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ 1: ๋ฌด์ฐจ๋ณ ๋์
์๊ฐ ๋ณต์ก๋: O(Nยฒ).
๊ณต๊ฐ ๋ณต์ก๋: O(1).
๊ฐ์ฅ ๋ถ๋ช ํ ์๋ฏธ๋ ํ ์์ ์ค์ฒฉ ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
const findSum = (arr, val) => {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (i !== j && arr[i] + arr[j] === val) {
return true;
};
};
};
return false;
};
์ด ์๋ฃจ์ ์ ๋ฐฐ์ด์ ์๋ ๋ ์์์ ๊ฐ๋ฅํ ๋ชจ๋ ํฉ์ ํ์ธํ๊ณ ๋ชจ๋ ์ธ๋ฑ์ค ์์ ๋ ๋ฒ ๋น๊ตํ๊ธฐ ๋๋ฌธ์ ํจ์จ์ ์ด์ง ์์ต๋๋ค. (์๋ฅผ ๋ค์ด i = 1์ด๊ณ j = 2์ธ ๊ฒฝ์ฐ ์ค์ ๋ก๋ i = 2 ๋ฐ j = 1๊ณผ ๋น๊ตํ๋ ๊ฒ๊ณผ ๋์ผํ์ง๋ง ์ด ์๋ฃจ์ ์์๋ ๋ ๊ฐ์ง ์ต์ ์ ๋ชจ๋ ์๋ํฉ๋๋ค.)
์ฐ๋ฆฌ ์๋ฃจ์ ์ ํ ์์ ์ค์ฒฉ for ๋ฃจํ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ O(Nยฒ) ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ๋ XNUMX์ฐจ์ ๋๋ค.
์๋ฃจ์ 2: ์ด์ง ๊ฒ์
์๊ฐ ๋ณต์ก๋: O(Nlog(N)).
๊ณต๊ฐ ๋ณต์ก๋: O(1).
๋ฐฐ์ด์ด ์ ๋ ฌ๋์ด ์์ผ๋ฏ๋ก ์ด์ง ๊ฒ์์ ์ฌ์ฉํ์ฌ ์๋ฃจ์ ์ ๊ฒ์ํ ์ ์์ต๋๋ค. ์ด๋ ์ ๋ ฌ๋ ๋ฐฐ์ด์ ๋ํ ๊ฐ์ฅ ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ์ด์ง ๊ฒ์ ์์ฒด์ ์คํ ์๊ฐ์ O(log(N))์ ๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ ์์๋ฅผ ๋ค๋ฅธ ๋ชจ๋ ๊ฐ๊ณผ ๋น๊ตํ๋ ค๋ฉด for ๋ฃจํ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
ํด๊ฒฐ์ฑ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋ช ํํ๊ฒ ํ๊ธฐ ์ํด ์ด์ง ๊ฒ์์ ์ ์ดํ๊ธฐ ์ํด ๋ณ๋์ ๊ธฐ๋ฅ์ ์ฌ์ฉํฉ๋๋ค. ๋ํ ์ฃผ์ด์ง ์ธ๋ฑ์ค๋ฅผ ๋บ ๋ฐฐ์ด ๋ฒ์ ์ ๋ฐํํ๋ RemoveIndex() ํจ์๋ ์์ต๋๋ค.
const findSum = (arr, val) => {
for (let i = 0; i < arr.length; i++){
if (binarySearch(removeIndex(arr, i), val - arr[i])) {
return true;
}
};
return false;
};
const removeIndex = (arr, i) => {
return arr.slice(0, i).concat(arr.slice(i + 1, arr.length));
};
const binarySearch = (arr, val) => {
let start = 0;
let end = arr.length - 1;
let pivot = Math.floor(arr.length / 2);
while (start < end) {
if (val < arr[pivot]) {
end = pivot - 1;
} else if (val > arr[pivot]) {
start = pivot + 1;
};
pivot = Math.floor((start + end) / 2);
if (arr[pivot] === val) {
return true;
}
};
return false;
};
์๊ณ ๋ฆฌ์ฆ์ ์ธ๋ฑ์ค [0]๋ถํฐ ์์๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ฒซ ๋ฒ์งธ ์ธ๋ฑ์ค๋ฅผ ์ ์ธํ ๋ฐฐ์ด ๋ฒ์ ์ ์์ฑํ๊ณ ์ด์ง ๊ฒ์์ ์ฌ์ฉํ์ฌ ๋๋จธ์ง ๊ฐ ์ค ํ๋๋ฅผ ๋ฐฐ์ด์ ์ถ๊ฐํ์ฌ ์ํ๋ ํฉ๊ณ๋ฅผ ์์ฑํ ์ ์๋์ง ํ์ธํฉ๋๋ค. ์ด ์์ ์ ๋ฐฐ์ด์ ๊ฐ ์์์ ๋ํด ํ ๋ฒ์ฉ ์ํ๋ฉ๋๋ค.
for ๋ฃจํ ์์ฒด๋ O(N)์ ์ ํ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ง for ๋ฃจํ ๋ด๋ถ์์๋ ์ด์ง ๊ฒ์์ ์ํํ์ฌ ์ ์ฒด ์๊ฐ ๋ณต์ก๋๊ฐ O(Nlog(N))์ ๋๋ค. ์ด ์๋ฃจ์ ์ ์ด์ ์๋ฃจ์ ๋ณด๋ค ์ฐ์ํ์ง๋ง ์ฌ์ ํ ๊ฐ์ ์ ์ฌ์ง๊ฐ ์์ต๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ 3: ์ ํ ์๊ฐ
์๊ฐ ๋ณต์ก๋: O(N).
๊ณต๊ฐ ๋ณต์ก๋: O(1).
์ด์ ๋ฐฐ์ด์ด ์ ๋ ฌ๋์์์ ๊ธฐ์ตํ๋ฉด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ฒ ์ต๋๋ค. ํด๊ฒฐ์ฑ ์ ๋ ๊ฐ์ ์ซ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ํ๋๋ ์์ ๋ถ๋ถ์ด๊ณ ๋ค๋ฅธ ํ๋๋ ๋ ๋ถ๋ถ์ ๋๋ค. ๊ฒฐ๊ณผ๊ฐ ํ์ํ ๊ฒฐ๊ณผ์ ๋ค๋ฅธ ๊ฒฝ์ฐ ์์์ ๊ณผ ๋์ ์ ๋ณ๊ฒฝํ์ญ์์ค.
๊ฒฐ๊ตญ ์ํ๋ ๊ฐ์ ๋ง๋ true๋ฅผ ๋ฐํํ๊ฑฐ๋, ์์์ ๊ณผ ๋์ ์ด ์๋ ดํ์ฌ false๋ฅผ ๋ฐํํ๊ฒ ๋ฉ๋๋ค.
const findSum = (arr, val) => {
let start = 0;
let end = arr.length - 1;
while (start < end) {
let sum = arr[start] + arr[end];
if (sum > val) {
end -= 1;
} else if (sum < val) {
start += 1;
} else {
return true;
};
};
return false;
};
์ด์ ๋ชจ๋ ๊ฒ์ด ์ ์์ด๋ฉฐ ์๋ฃจ์ ์ด ์ต์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ํ์ง๋ง ์ด๋ ์ด๊ฐ ์ฃผ๋ฌธ๋์๋์ง ๋๊ฐ ๋ณด์ฅํ ์ ์์ต๋๊น?
๊ทธ ๋ ๋ฌด์?
์ผํ ๋ณด๋ฉด ๋จ์ํ ์ด๋ ์ด๋ฅผ ๋จผ์ ์ฃผ๋ฌธํ ๋ค์ ์์ ์๋ฃจ์ ์ ์ฌ์ฉํ ์๋ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์คํ ์๊ฐ์ ์ด๋ค ์ํฅ์ ๋ฏธ์น ๊น์?
๊ฐ์ฅ ์ข์ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋๊ฐ O(Nlog(N))์ธ ํต ์ ๋ ฌ์ ๋๋ค. ์ด๋ฅผ ์ต์ ์ ์๋ฃจ์ ์ ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ์ด O(N)์์ O(Nlog(N))์ผ๋ก ๋ณ๊ฒฝ๋ฉ๋๋ค. ์ ๋ ฌ๋์ง ์์ ๋ฐฐ์ด๋ก ์ ํ ์๋ฃจ์ ์ ์ฐพ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๊น?
4 ์๋ฃจ์
์๊ฐ ๋ณต์ก๋: O(N).
๊ณต๊ฐ ๋ณต์ก๋: O(N).
์, ์ ํ ์๋ฃจ์ ์ด ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ์ฐพ๊ณ ์๋ ์ผ์น ํญ๋ชฉ ๋ชฉ๋ก์ด ํฌํจ๋ ์ ๋ฐฐ์ด์ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ์์ ์ ์ถฉ์ ์ ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ๋๋ค. ์ด๋ ๋ ผ๋ฌธ์์ ๊ณต๊ฐ ๋ณต์ก๋๊ฐ O(1)๋ณด๋ค ํฐ ์ ์ผํ ์๋ฃจ์ ์ ๋๋ค.
์ฃผ์ด์ง ๋ฐฐ์ด์ ์ฒซ ๋ฒ์งธ ๊ฐ์ด 1์ด๊ณ ๊ฒ์ ๊ฐ์ด 8์ธ ๊ฒฝ์ฐ "๊ฒ์ ๊ฐ" ๋ฐฐ์ด์ ๊ฐ 7์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๊ทธ๋ฐ ๋ค์ ๋ฐฐ์ด์ ๊ฐ ์์๋ฅผ ์ฒ๋ฆฌํ๋ฉด์ "๊ฒ์ ๊ฐ" ๋ฐฐ์ด์ ํ์ธํ๊ณ ๊ทธ ์ค ํ๋๊ฐ ์ฐ๋ฆฌ ๊ฐ๊ณผ ๊ฐ์์ง ํ์ธํ ์ ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด true๋ฅผ ๋ฐํํฉ๋๋ค.
const findSum = (arr, val) => {
let searchValues = [val - arr[0]];
for (let i = 1; i < arr.length; i++) {
let searchVal = val - arr[i];
if (searchValues.includes(arr[i])) {
return true;
} else {
searchValues.push(searchVal);
}
};
return false;
};
์๋ฃจ์ ์ ๊ธฐ๋ณธ์ ์์์ ๋ณธ ๊ฒ์ฒ๋ผ O(N)์ ์ ํ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ๋ for ๋ฃจํ์ ๋๋ค.
ํจ์์ ๋ ๋ฒ์งธ ๋ฐ๋ณต ๋ถ๋ถ์ ๋ฐฐ์ด์ ์ง์ ๋ ๊ฐ์ด ํฌํจ๋์ด ์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ true ๋๋ false๋ฅผ ๋ฐํํ๋ JavaScript ๋ฉ์๋์ธ Array.prototype.include()์ ๋๋ค.
Array.prototype.includes()์ ์๊ฐ ๋ณต์ก๋๋ฅผ ํ์ ํ๊ธฐ ์ํด MDN์์ ์ ๊ณตํ๊ณ JavaScript๋ก ์์ฑ๋ ํด๋ฆฌํ์ ๋ณด๊ฑฐ๋ Google V8(C++)๊ณผ ๊ฐ์ JavaScript ์์ง์ ์์ค ์ฝ๋์ ์๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(valueToFind, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n โฅ 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(valueToFind, elementK) is true, return true.
if (sameValueZero(o[k], valueToFind)) {
return true;
}
// c. Increase k by 1.
k++;
}
// 8. Return false
return false;
}
});
}
์ฌ๊ธฐ์ Array.prototype.include()์ ๋ฐ๋ณต ๋ถ๋ถ์ ์ฃผ์ด์ง ๋ฐฐ์ด์ ์ ์ฒด ๊ธธ์ด๋ฅผ (๊ฑฐ์) ์ํํ๋ 7๋จ๊ณ์ while ๋ฃจํ์ ๋๋ค. ์ด๋ ์๊ฐ ๋ณต์ก๋๋ ์ ํ์์ ์๋ฏธํฉ๋๋ค. ์, ํญ์ ๋ฉ์ธ ๋ฐฐ์ด๋ณด๋ค ํ ๋จ๊ณ ๋ค์ฒ์ง๊ธฐ ๋๋ฌธ์ ์๊ฐ ๋ณต์ก๋๋ O(N + (N - 1))์ ๋๋ค. Big O ํ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ O(N)์ผ๋ก ๋จ์ํํฉ๋๋ค. ์ ๋ ฅ ํฌ๊ธฐ๋ฅผ ๋๋ฆด ๋ ๊ฐ์ฅ ํฐ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ N์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ณต๊ฐ ๋ณต์ก์ฑ๊ณผ ๊ด๋ จํ์ฌ ๊ธธ์ด๊ฐ ์๋ ๋ฐฐ์ด์ ๋ฐ์ํ๋ ์ถ๊ฐ ๋ฐฐ์ด์ด ํ์ํ๋ฏ๋ก(XNUMX ๋นผ๊ธฐ, ์, ๊ทธ๋ฌ๋ ๋ฌด์ํ ์ ์์) O(N) ๊ณต๊ฐ ๋ณต์ก์ฑ์ด ๋ฐ์ํฉ๋๋ค. ์, ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋์ด๋๋ฉด ์๊ณ ๋ฆฌ์ฆ์ ํจ์จ์ฑ์ด ๊ทน๋ํ๋ฉ๋๋ค.
์ด ๊ธฐ์ฌ๊ฐ ๋น๋์ค ์ธํฐ๋ทฐ์ ๋ณด์ถฉ์๋ฃ๋ก ์ ์ฉํ๊ธธ ๋ฐ๋๋๋ค. ์ด๋ ๊ฐ๋จํ ๋ฌธ์ ๊ฐ ๋ค์ํ ์์ ๋ฆฌ์์ค(์๊ฐ, ๋ฉ๋ชจ๋ฆฌ)๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ํด๊ฒฐ๋ ์ ์์์ ๋ณด์ฌ์ค๋๋ค.
Skillbox๋ ๋ค์์ ๊ถ์ฅํฉ๋๋ค.
- ์จ๋ผ์ธ ๊ฐ์ข ์ ์ฉ
"ํ์ด์ฌ ๋ฐ์ดํฐ ๋ถ์๊ฐ" .- ์จ๋ผ์ธ ์ฝ์ค
"์ง์ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์" .- ์ค๊ธฐ ์ฝ์ค
"0์์ PRO๋ก์ PHP ๊ฐ๋ฐ์" .
์ถ์ฒ : habr.com