-
프로그래머스 알고리즘 복습하기알고리즘, 자료구조/프로그래머스 2020. 8. 4. 17:17
최적해를 구해야 되는 문제, 완전 탐색을 해야 되는 문제는 개인적으로 어려워하는 유형이라 이미 풀어봤던 문제일지라도 다시 풀어보면서 복습해야 될 것 같다. 틈틈이 업데이트하자!
앞으로는 github에 업데이트하기: https://github.com/jaemin-jeong/algorithm-programmers
jaemin-jeong/algorithm-programmers
Programmers algorithm training : https://programmers.co.kr/ - jaemin-jeong/algorithm-programmers
github.com
완전 탐색, DFS, BFS
1. 타겟 넘버 https://programmers.co.kr/learn/courses/30/lessons/43165 (O)
모든 경우를 탐색해 계산 결과가 타겟과 동일한 경우의 수를 찾는 문제이기 때문에 이전과 마찬가지로 DFS로 풀이했다.// 이전에 작성한 코드 function solution(numbers, target) { var answer = 0; let index = 0, calc = 0; const dfsRecursion = (i, sum) => { while(i < numbers.length){ i = i + 1 dfsRecursion(i, sum+numbers[i - 1]); dfsRecursion(i, sum-numbers[i - 1]); } return sum === target ? answer++ : answer; } dfsRecursion(index, calc); return answer; } // 복습 코드 function solution(numbers, target) { let answer = 0; search(0, 0); function search(sum, depth){ if(depth === numbers.length){ return sum === target ? answer++ : answer; } search(sum + numbers[depth], depth + 1); search(sum - numbers[depth], depth + 1); } return answer; }
2. 네트워크 https://programmers.co.kr/learn/courses/30/lessons/43162 (O)
모든 경우를 탐색해 연결된 컴퓨터를 네트워크로 묶은 후 총 네트워크 개수를 구하는 문제이기 때문에 DFS로 풀이했다. 예전에는 stack으로 해결하는 게 더 쉽게 느껴졌는데, pseudo-code를 다시 작성하다보니 이번 복습에서는 재귀로 풀게되었다.// 이전 코드 function solution(n, computers) { let answer = 0, stack = [], i = 0, count = 0, passed = []; while(count < n){ for(let j = 0; j < n; j++){ if(computers[i][j] === 1 && !passed.includes(j)){ stack.push(j); passed.push(j); }; }; if(stack.length > 0){ i = stack.pop(); } if(stack.length === 0){ answer++; i = 0; while(passed.includes(i)){ i++; } } count++; } return answer; } // 복습 코드 function solution(n, computers) { let answer = 0, check = new Map(); for(let i = 0; i < n; i++){ check.set(i, true) }; const search = (com) => { check.set(com, false); computers[com].forEach((v, i) => { if(check.get(i) && v === 1) search(i); }); return; } for(let i = 0; i < n; i++){ if(check.get(i)){ search(i); answer++; }; } return answer; }
3. 카펫 https://programmers.co.kr/learn/courses/30/lessons/42842 (O)완전 탐색 문제로서 모든 경우를 체크하면 된다. 이전과 동일하게 브루트 포스(Brute-force) 알고리즘으로 문제를 해결했다. 달라진 점이라면 ①변수명을 보다 직관적으로 작성한 것 ②제약조건(가로길이 >= 세로 길이, 갈색 테두리 줄은 1)을 통해 최대/최소값을 구하여 조건식에 부합하는지 판단하고 판단 여부에 따라 반복문을 도는 로직으로 구현하여 코드 길이는 줄이고 가독성은 높였다는 것이 있겠다.
// 이전 코드 function solution(brown, yellow) { let answer = []; let row, col; row = Math.ceil(Math.sqrt(brown + yellow)); if(Math.sqrt(brown + yellow) % 1 === 0){ answer[0] = row; answer[1] = row; }else{ for(let i = row - 2; i <= yellow; i++){ col = yellow / i; if((i + 2) * (col + 2) === brown + yellow){ row = i; answer[0] = row + 2; answer[1] = col + 2; break; } } } return answer; } // 복습 코드 function solution(brown, yellow) { let answer = []; let yellowMinX = Math.ceil((brown - 4) / 4); let yellowMaxY = Math.floor((brown - 4) / 4); while (true) { if(yellowMaxY * yellowMinX === yellow) { answer.push(yellowMinX + 2); answer.push(yellowMaxY + 2); return answer; } yellowMinX++; yellowMaxY--; } }
https://programmers.co.kr/learn/courses/30/lessons/43163 ()
https://programmers.co.kr/learn/courses/30/lessons/43164 ()https://programmers.co.kr/learn/courses/30/lessons/42840 ()
https://programmers.co.kr/learn/courses/30/lessons/42839 ()탐욕법
1. 큰 수 만들기 https://programmers.co.kr/learn/courses/30/lessons/42883 ()
탐욕법(greedy algorithm)은 모든 문제의 해결 방안은 아니다. 탐욕법으로 풀었을 때 최적의 해를 구하지 못하는 경우도 있기 때문에, 탐욕법으로 일단 풀어보고 안되면 빨리 다른 방법으로 해결하는게 시간을 아끼는 방법이다. 이 문제를 단순하게 생각하면, ①작은 수 순서대로 정렬하고 k개를 제거한다 ②큰 수 부터 차례대로 이어 붙이면 큰 수가 된다.
// 이전 코드 function solution(num, k) { let answer = []; let i = 0; let rest = num.length - k; let number = [...new Set(num.split('').sort((a, b) => b - a))]; while(rest > 0){ let delStart = (num.indexOf(number[i])) + 1; answer.push(number[i]); if(!num.includes(number[i]) || num.slice(delStart).length < rest - 1){ answer.pop(); i++; continue; } num = num.slice(delStart); rest--; i = 0; } return answer.join(''); }
동적 계획법
https://programmers.co.kr/learn/courses/30/lessons/43105 ()
https://programmers.co.kr/learn/courses/30/lessons/42895 ()스택/큐
1. 다리위를 지나는 트럭 programmers.co.kr/learn/courses/30/lessons/42583(O)
큐를 이용하면 되는 문제이고, 이번 풀이에서는 불필요한 변수 선언이나 과정을 최대한 피해 코드를 작성하려 노력했다.
// 이전 코드 function solution(bridge_length, weight, truck_weights) { let answer = 0; let done = []; let onBridge = []; let restTime = []; let count = truck_weights.length; while(done.length < count){ let tmp = 0; if(truck_weights.length > 0){ tmp = truck_weights.shift(); onBridge.push(tmp); restTime.push(bridge_length); } let sum = onBridge.reduce((a, b) => { a += b; return a; }) if(weight >= sum){ restTime = restTime.map(t => { t--; return t; }); answer++; if(restTime[0] <= 0){ restTime.shift(); let d = onBridge.shift(); done.push(d); } }else{ if(tmp !== 0){ truck_weights.unshift(tmp); onBridge.pop(); restTime.pop(); tmp = 0; } while(restTime[0] > 0){ restTime = restTime.map(t => { t--; return t; }); answer++; } restTime.shift(); let d = onBridge.shift(); done.push(d); } } return answer + 1; } // 복습 코드 function solution(bridge_length, weight, truck_weights) { let answer = 0; let queue = []; let lenList = []; let curWeight = 0; while (truck_weights.length > 0 || queue.length > 0) { if (truck_weights[0] && weight >= curWeight + truck_weights[0]) { let truck = truck_weights.shift(); // queue에 트럭 추가, 현재 무게에 트럭 무게 추가 queue.push(truck); curWeight += truck; // lenList 다리에 오른 트럭이 다리를 벗어나기까지 남은 거리 추가 lenList.push(bridge_length); } lenList = lenList.map(len => len - 1); answer++; // 남은 거리가 0이면 lenList, queue에서 빼내기 if (lenList[0] === 0){ lenList.shift(); curWeight -= queue[0]; queue.shift(); } } answer++; return answer; };
'알고리즘, 자료구조 > 프로그래머스' 카테고리의 다른 글
[Javascript] 프로그래머스 - 위장 (0) 2022.09.19 [Javascript] 프로그래머스 디스크 컨트롤러 (0) 2021.03.24 [Javascript] 프로그래머스 보석 쇼핑 (0) 2020.07.10 [Javascript] 프로그래머스 큰 수 만들기 (0) 2020.07.03 [Javascript] 프로그래머스 프린터 (0) 2020.06.30