04 λ¬Έμ ν΄κ²° ν¨ν΄
4.1 λνμ μΈ ν¨ν΄λ€
λ¬Έμ ν΄κ²° μ κ·Όλ²μ μ΄μ΄μ§λ λ΄μ©μΌλ‘ μ΄μ λ λλλ‘ μ μ©νκ² μ¬μ©ν μ μλ λͺ κ°μ§ μΌλ°μ μΈ ν¨ν΄μ μ΄ν΄λ³΄λ € νλ€. κ΅μ₯ν λ§μ ν¨ν΄λ€μ΄ μ‘΄μ¬νμ§λ§ λνμ μΈ ν¨ν΄λ€λ§ μ΄ν΄λ³΄μ.(곡μμ μΈ μ΄λ¦μ΄ λΆμ ν¨ν΄λ€λ μμ§λ§, κ·Έλ μ§ μμ ν¨ν΄λ€λ μ‘΄μ¬νλ€.)
1. Frequency Counter λΉλμ μΈκΈ° ν¨ν΄ (κ°μ¬λμ΄ μ§μ λΆμΈ μ΄λ¦μ΄λ€)
2. Multiple Pointers λ€μ€ ν¬μΈν° ν¨ν΄ (κ°μ¬λμ΄ μ§μ λΆμΈ μ΄λ¦μ΄λ€)
3. Sliding Window κΈ°μ€μ κ° μ΄λ λ°°μ΄ ν¨ν΄
4. Divide and Conquer λΆν κ³Ό μ 볡 ν¨ν΄ (곡μμ μΈ μ΄λ¦μ΄λ€. μ€μ μμ£Ό μ¬μ©λ¨)
5. Greedy Algorithms νμ μκ³ λ¦¬μ¦ ν¨ν΄ (μ€μ μμ£Ό μ¬μ©λ¨)
μ΄ μ²λΌ λ¬Έμ ν΄κ²°μ μ μ©νκ² μ¬μ©ν μ μλ ν¨ν΄λ€μ΄ λ§μ΄ μ‘΄μ¬νλ€.
4.2 Frequency Counter λΉλμ μΈκΈ° ν¨ν΄ (곡μμ μΈ μ΄λ¦μ μλ€)
λΉλμ μΈκΈ° ν¨ν΄μ λ³΄ν΅ μλ°μ€ν¬λ¦½νΈμ κ°μ²΄λ₯Ό μ¬μ©ν΄μ λ€μν κ°κ³Ό λΉλλ₯Ό μμ§ν λ μ μ©νκ² μ¬μ©ν μ μλ ν¨ν΄μ΄λ€. μ΄ ν¨ν΄μ μ¬λ¬ λ°μ΄ν°μ μ λ ₯κ°μ΄ μλ‘ λΉμ·ν κ°μΌλ‘ ꡬμ±λμ΄ μλμ§, μλ‘ κ°μ μλκ·Έλ¨(λ§ μ₯λμμ μ λ‘)μΈμ§, κ°μ΄ λ€λ₯Έ κ°μ ν¬ν¨λλμ§ μ¬λΆλ₯Ό λΉκ΅ν λ μ μ©νλ€.
μλ₯Όλ€μ΄, '2κ°μ λ°°μ΄μ νμ©νλ arrayCompare λΌλ ν¨μλ₯Ό μμ±νλ€'κ³ μκ°ν΄λ³΄μ. μ΄ ν¨μλ μ²μμΌλ‘ μ λ ₯λ°μ λ°°μ΄μ λͺ¨λ κ°μ μ κ³±μ΄ λ λ²μ§Έλ‘ μ λ ₯λ°μ λ°°μ΄μ λͺ¨λ ν¬ν¨λμ΄ μλμ§ μκΈ° μν ν¨μλ€. μμλ μκ΄μμ§λ§ λ λ°°μ΄μ μμ κ°μλ λμΌν΄μΌ νλ€.
ex) [1, 2, 3] [1, 4, 9] -> true
λΉλμ μΈκΈ° ν¨ν΄μ μ¬μ©νμ§ μκ³ μμ±ν΄λ³΄μ
function arrayCompare(array1, array2){
if(array1.length !== array2.length){
return false;
}
for(let i = 0; i < array1.length; i++){ //μ€μ
let correctInd = array2.indexOf(array1[i] ** 2) //μΈλ±μ€μ€λΈκ° μ€μμ
if(correctInd === -1) {
return false;
}
console.log(array2);
array2.splice(correctInd,1)
}
return true;
}//μ€μμ κ³± μκ°λ³΅μ‘λλ₯Ό κ°μ
console.log(arrayCompare([1,2,3,2], [9,1,4,4]))
μμ κ°μ΄ μ½λλ₯Ό μμ±νλ©΄ O(N^2) μκ° λ³΅μ‘λλ₯Ό κ°λ ν¨μκ° μμ±λλ€. μ΄λ²μλ ν¨ν΄μ μ¬μ©ν΄μ μμ±ν΄ 보μ.
function arrayCompare(array1, array2){
if(array1.length !== array2.length){
return false;
}
let freCounter1 = {}
let freCounter2 = {}
for(let foo of array1){
freCounter1[foo] = (freCounter1[foo] || 0) + 1
}
for(let foo of array2){
freCounter2[foo] = (freCounter2[foo] || 0) + 1
}
console.log(freCounter1);
console.log(freCounter2);
for(let bar in freCounter1){
if(!(bar ** 2 in freCounter2)){
return false
}
if(freCounter2[bar ** 2] !== freCounter1[bar]){
return false
}
}
return true
}
arrayCompare([1,2,3,2,5], [9,1,4,4,11])
O(N) μκ° λ³΅μ‘λλ₯Ό κ°λ ν¨μλ₯Ό μμ±ν μ μλ€. μ΄λ₯Ό ν΅ν΄ μ±λ₯λ©΄μμλ λ°μ΄λ ν¨μλ₯Ό μμ±ν μ μλ€.(μ¬μ€ μ΄λ κ² κ°μμμ λ°°μ μ§λ§, λ무 μ½λκ° λ³΅μ‘ν건 μλκ° νλ μꡬμ¬μ λ λ€..)
4.3 μλκ·Έλ¨
μλκ·Έλ¨μ΄λ μΌμ’ μ λ§μ₯λμΌλ‘ μ΄λ ν λ¨μ΄μ λ¬Έμλ₯Ό μ¬λ°°μ΄νμ¬ λ€λ₯Έ λ»μ κ°μ§λ λ€λ₯Έ λ¨μ΄λ‘ λ°κΎΈλ κ²μ λ§νλ€. μ¦, 'apple'μ'elpap'μ²λΌ λ¬Όλ‘ λ§μ λμ§λ§ κ°μ λ¬Έμλ€μ κ°μ§κ³ μμ§λ§, μμκ° λ€λ₯Έκ²μ μλκ·Έλ¨μ΄λΌκ³ νλ€. μ°λ¦¬κ° μ¬κΈ°μ νμ΄μΌ ν λ¬Έμ λ λ κ°μ λ¬Έμμ΄μ μ λ ₯λ°μ λ λ¬Έμμ΄μ΄ μλ‘μ μλκ·Έλ¨μ΄λ©΄ μ°Έμ μλκ·Έλ¨μ΄ μλλΌλ©΄ κ±°μ§μ λ°ννλ ν¨μλ₯Ό ꡬμ±νλκ²μ΄ λͺ©νλ€. μ΄λ νμ©ν μ μλ κ²μ΄ λ°λ‘ λ¬Έμμ΄ μΈκΈ° ν¨ν΄μ΄λ€. ν¨ν΄μ μ΄μ©ν΄μ μλκ·Έλ¨ ν¨μλ₯Ό λ§λ€μ΄λ³΄μ.
function anagram(string1,string2){
if(string1.length !== string2.length){
return false;
}
let strObject1 = {};
let strObject2 = {};
for(let i of string1){
strObject1[i] = (strObject1[i] || 0) + 1; // κ°μ²΄μμ μ κ·Ό ν νλ‘νΌν°κ° μμΌλ©΄, undefinedλ₯Ό λ°ννλ―λ‘ falsyκ° λκ³ falseκ°μΌλ‘ μ묡μ νμ
λ³νλμ΄ λ€μ κ°μ΄ λ°νλ¨
}
for(let i of string2){
strObject2[i] = (strObject2[i] || 0) + 1;
}
for(let i in strObject1){
if(!(i in strObject2)){
return false;
}
if(strObject2[i] !== strObject1[i]){
return false;
}
}
return true;
}
console.log(anagram("cat","bus")); // false
μ¦, μ μ½λμ²λΌ λ¬Έμμ΄μ΄λ λ°°μ΄μμ λ€μ΄μλ κ°λ€μ΄ λͺ κ° μλμ§ μΉ΄μ΄νΈνμ¬ κ°μ²΄λ‘ λ§λ€κ³ λΉκ΅νλκ² λΉλ μ μΈκΈ° ν¨ν΄μ΄λ€. λ°λ³΅λ¬Έμ μ μ©νμ¬ λ§λ κ°μ²΄λ₯Ό μ¬μ©νκ³ μ€μ²©λμ§ μμ λ λ²μ§Έ λ°λ³΅λ¬Έμ μ¬μ©ν΄μΌ νλ€. κ·Έλ κ² λ§λ λ€λ©΄ O(N) μκ° λ³΅μ‘λλ₯Ό μ μ§ν μ μλ€.
λ€μ λ§ν΄ 첫 λ²μ§Έ μ λ ₯λ°μ κ°μ μΈλΆννμ¬ κ°μ²΄μ κ° λ¬Έμ λλ μμμ κ°μλ₯Ό μΉ΄μ΄νΈν΄μ νλ‘νΌν°λ‘ λ§λ€κ³ , λ λ²μ§Έ κ°κ³Ό λΉκ΅ν΄ κ°λ©΄μ νλ νλ μ§μλκ°λ©΄μ λΉκ΅νλκ²μ΄ λ°λ‘ λΉλμ μΈκΈ° ν¨ν΄ λ°©λ²μ΄λ€. μ΄λ¬ν λΉλμ μΈκΈ° ν¨ν΄μ μ«μκ° κ°μ μ«μλ‘λ§ κ΅¬μ±λμ΄ μκ³ , μμλ§ λ€λ₯Έμ§ νμΈν΄μΌ νλ κ²½μ° λ±μ μμ©μ΄ κ°λ₯ν ν¨ν΄μ΄λ€. μ¦ λ κ°μ λΉκ΅ν λ λΉκ΅κ° μ©μ΄νλ€.
4.4 λ€μ€ ν¬μΈν° ν¨ν΄ (곡μμ μΈ μ΄λ¦μ΄ μλ ν¨ν΄μ΄λ€)
μ΄ ν¨ν΄μ μ μλ μΈλ±μ€λ μμΉμ ν΄λΉνλ ν¬μΈν°λ₯Ό λ§λ λ€μ νΉμ 쑰건μ λ°λΌ μ€κ° μ§μ μμλΆν° μμ μ§μ μ΄λ λ μ§μ , λλ μμͺ½ μ§μ μ ν₯ν΄ μ΄λμν€λ κ²μ΄λ€. ν΅μ¬μ λ κ°μ ν¬μΈν°λ₯Ό μ¬μ©νλ€λ κ²μ΄λ€.
μλ₯Ό λ€μ΄, μ λ ¬λ λ°°μ΄μ μ λ ₯λ°μ sumZero ν¨μλ₯Ό λ§λ λ€κ³ ν΄λ³΄μ. μ΄ ν¨μλ ν©κ³κ° 0μΈ μ²« λ²μ§Έ μ μ¦, ν μ«μλ₯Ό κ°μ Έμ λ€λ₯Έ μ«μμ λνλ©΄ 0μ΄ λλ ν μμ μ°Ύλ ν¨μμ΄λ€. μ£Όμν΄μΌ ν μ μ μ λ ¬λ λ°°μ΄μ μ λ ₯λ°μμΌ νλ©°, μ€λ¦μ°¨μμΌλ‘ λμ΄ μμ΄μΌ νλ€.
ex)
[-3, -2, -1, 0, 1, 2, 3] -> [-3, 3]μ λ°νν¨
[-2, 0, 1, 3] -> undefinedλ₯Ό λ°νν¨(ν©μ΄ 0μΈ μμ΄ μμΌλ―λ‘)
ν¨ν΄μ μ¬μ©νμ§ μκ³ μ½λλ₯Ό μμ±ν΄ 보μ.
function sumZero(array){
for(let i = 0; i < array.length; i++){
for(let j = i+1 ; j < array.length; j++){
if(array[i] + array[j] === 0){
return [array[i], array[j]];
}
}
}
}
μ μ½λλ λ°λ³΅λ¬Έμ μ€μ²©ν΄μ μ¬μ©νμ¬ O(N^2)μκ° λ³΅μ‘λλ₯Ό κ°λ ν¨μκ° λλ€. μ¦, νλμ μμλ₯Ό κΈ°μ€μΌλ‘ λͺ¨λ μμλ€μ νλ νλ λ€ λΉκ΅νκ² λλ€.
λ€μ€ ν¬μΈν° ν¨ν΄μ μ μ©ν΄μ μ½λλ₯Ό μμ±ν΄ 보μ.
function sumZero(array){
let left = 0;
let right = array.length - 1;
while(left < right){
let sum = array[left] + array[right];
if(sum === 0){
return [array[left], array[right]];
} else if(sum > 0){
right--;
} else {
left++;
}
}
}
μμ λ€μ€ ν¬μΈν° ν¨ν΄μ μ΄μ©νλ©΄ O(N)μκ° λ³΅μ‘λλ₯Ό κ°λ μ½λλ₯Ό μμ±ν μ μλ€. μ¦ λ κ°μ ν¬μΈν°λ₯Ό λ§λ€μ΄μ λ κ°μ ν©μ΄ μλ³΄λ€ μλ€λ©΄ μΌμͺ½ ν¬μΈν°λ₯Ό ν μΉΈ μμ§μ΄κ³ , λ κ°μ ν©μ΄ 0λ³΄λ€ ν¬λ€λ©΄ μ€λ₯Έμͺ½ ν¬μΈν°λ₯Ό μμΌλ‘ μ΄λνλ©΄μ λ μμμ ν©μ΄ 0μΈ λ°°μ΄μ λ°ννλ€.
4.5 Sliding Window ν¨ν΄ κΈ°μ€μ κ° μ΄λ λ°°μ΄ ν¨ν΄
μ¬λΌμ΄λ© μλμ° ν¨ν΄μ λ¨μΌ λ³μ, νμ λ°°μ΄, λλ νμν κ²½μ° λ¬Έμμ΄μ μ λ ₯λ°μ 쑰건μ λ°λΌ μλμ°(μ°½λ¬Έ)μ μλμν€λ©° ν΄λΉ λ°μ΄ν°μ νμ μ§ν©μ μ°Ύλ κ²½μ°μ μ μ©νλ€.(μμ μμΉμμ μμνλ©΄ λ³΄ν΅ μΌμͺ½μμ μ€λ₯Έμͺ½μΌλ‘ μ΄λ, λ°λλ‘λ κ°λ₯νλ€)
ex)κ°μ₯ κΈ΄ μνμ€λ₯Ό μ°ΎμλΌ "hellomyworld" -> "hel/lomyw/orld" -> "lomyw"κ° κ°μ₯ κΈ΄ μνμμ΄λ€. μ΄λ° κ²½μ°μ μ μ©νκΈ° μ μ©ν ν¨ν΄μ΄ λ°λ‘ μ¬λΌμ΄λ© μλμ° ν¨ν΄μ΄λ€.
μμ λ¬Έμ ) λ°°μ΄μμ 쑰건μ λ§λ ν©μ΄ κ°μ₯ ν° μνμ€μ ν©μ 무μμΈκ°?
ex) maxSum([1, 2, 5, 2, 8, 1, 5], 2) -> 10μ΄λ€(2κ°μ μ°μνλ μμλ€ μ€ κ°μ₯ ν©μ΄ ν° μμμ ν©μ λ°ννλ ν¨μλ₯Ό νΈμΆ ν¨)
ν¨ν΄μ μ¬μ©νμ§ μκ³ ν¨μλ₯Ό λ§λ€μ΄ 보μ.
function maxSum(array, number) {
if ( number > array.length){
return null;
}
var max = -Infinity;
for (let i = 0; i < array.length - number + 1; i ++){
temp = 0;
for (let j = 0; j < number; j++){
temp += array[i + j];
}
if (temp > max) {
max = temp;
}
}
return max;
}
O(N^2) μκ° λ³΅μ‘λλ₯Ό κ°λ ν¨μλ₯Ό ν΅ν΄ ν΄λΉ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ€.(λ°λ³΅λ¬Έ μ€μ²© μ¬μ©)
μ΄λ²μλ ν¨ν΄μ μ¬μ©νμ¬ λ¬Έμ λ₯Ό ν΄κ²°ν΄ 보μ.
function maxSum(array, number){
let max = 0;
let temp = 0;
if (array.length < number) return null;
for (let i = 0; i < number; i++) {
max += array[i];
}
temp = max;
for (let i = number; i < array.length; i++) {
temp = temp - array[i - number] + array[i];
max = Math.max(max, temp);
}
return max;
}
ν¨ν΄μ μ¬μ©νμ¬ O(N) μκ° λ³΅μ‘λλ₯Ό κ°λ ν¨μ¨μ μΈ μ½λλ₯Ό μμ±ν μ μλ€.
4.6 Divide and Conquer λΆν κ³Ό μ 볡 (곡μνλ μ΄λ¦μ΄λ€)
μ΄ μκ³ λ¦¬μ¦μ μ£Όλ‘ λ°°μ΄μ΄λ λ¬Έμμ΄ κ°μ ν° κ·λͺ¨μ λ°μ΄ν°μ μ μ²λ¦¬νλ€. λ°λ‘ μ΄λ€ ν¨ν΄μΈμ§ μμ λ₯Ό ν΅ν΄ νμΈν΄ 보μ.
μμ ) indexSearch([1, 2, 3, 4, 5, 6], 4) // 3λ°ν (μμμΈ 4κ° μμΉνλ μΈλ±μ€ λ²νΈλ₯Ό λ°ννλ ν¨μλ₯Ό νΈμΆνμ)
λΆν κ³Ό μ 볡 ν¨ν΄μ μ¬μ©νμ§ μκ³ ν¨μλ₯Ό λ§λ€μ΄ 보μ.
function indexSearch(array, foo){
for(let i = 0; i < array.length; i++){
if(array[i] === foo){
return i;
}
}
return -1;
}
function indexSearch(array, foo) {
let min = 0;
let max = array.length - 1;
while (min <= max) {
let mid = Math.floor((min + max) / 2);
let currentEle = array[mid];
if (array[mid] < foo) {
min = mid + 1;
}
else if (array[mid] > foo) {
max = mid - 1;
}
else {
return mid;
}
}
return -1;
}
μμ μ½λκ° μλλλ λ°©λ²μ νμΈν΄ 보μ. μλ₯Όλ€μ΄ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]μ λ°°μ΄μμ 9λ₯Ό μ°Ύμ μΈλ±μ€λ₯Ό λ°νν΄μΌ νλ€λ©΄ μ€κ°μΈ 5λ₯Ό μ ννκ³ μ°ΎμμΌνλ 9λ³΄λ€ μκΈ° λλ¬Έμ 5λ₯Ό ν¬ν¨νλ μλ μμλ€μ λ€ λ¬΄μνλ€. κ·Έλ¦¬κ³ λλ¨Έμ§ 6λΆν° 10κΉμ§μ νμ λ°°μ΄μ μ΄ν΄λ³Έλ€. κ·Έλ¦¬κ³ λ€μ 6μμ 10μ¬μ΄μ μ€κ°μΈ 7μ μ νν΄μ νμΈνκ³ 9λ³΄λ€ μκΈ° λλ¬Έμ νμλ°°μ΄μ 7μλλ‘λ λ€ λ¬΄μνλ€. λλ¨Έμ§μ μ€κ°μΈ 9λ₯Ό μ ννκ³ ν΄λΉ κ°μ μ°ΎμκΈ° λλ¬Έμ ν΄λΉκ°μ μΈλ±μ€ λ²νΈλ₯Ό λ°ννλ€. μ¦, ν° λ°°μ΄μ΄λ λ¬Έμμ΄μμ νΉμ μμλ λ¬Έμλ₯Ό μ°Ύμ λ νλ νλ λ€ λΉκ΅νλκ²μ΄ μλλΌ μ€κ° μ§μ μ μ°Ύμ νμμλ λΆλΆμ 무μνκ³ λΉκ΅νκ³ , λ λλ¨Έμ§ νμλ°°μ΄ λλ λ¬Έμμ΄μμ μ€κ° μ§μ μ μ νν΄μ λΉκ΅νμ¬ μνλ μμ λλ λ¬Έμμλ₯Ό μ°Ύλ λ°©λ²μ΄λ€. ν λ§λλ‘ ν° λ°μ΄ν°μ μ μ·¨ν΄ μμ νμμ μΌλ‘ λΆν νμ¬ μνλ κ°μ μ°Ύλ κ²μ΄λ€.