무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.
예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다.
구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다.
사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요.
people | limit | return |
---|---|---|
[70, 50, 80, 50] | 100 | 3 |
[70, 80, 50] | 100 | 3 |
배열 people을 오름차순으로 정렬한다.
limit - 40 보다 작거나 같은 값과 filter해서 변수에 저장(limit - 40보다 큰 수는 가장 작은 수인 40kg가 더해도 limit를 초과하기 때문에)하고 그 반대의 경우도 변수에 따로 저장한다.
이중 for 문을 돌려서 human[i] + human[j]가 limit보다 작거나 같다면 human[j] 값을 삭제하고 다시 상위 for 문이 돌도록 break; 시켜준다.
ex: limit = 100, human = [20, 30, 40, 50] 이라면 human[i] = 20, human[j] = 50 이고 조건에 맞으니 50을 배열에서 제거한 뒤 조건문을 끝낸다.
이 작업을 반복해서 human의 길이 값을 구한다.
human = [20, 30, 40, 50] 이라면
human = [20, 30] 이 되고, human.length = 2가 된다.
결국 20kg + 50kg = 구명보트 1개, 30kg + 40kg = 구명보트 1개 총 2개의 구명보트를 탈 수 있고 이 값은 human의 길이 값과 동일하다.
limit - 40을 filter한 배열 값(구명보트를 혼자서 타야만 하는 사람 수)과 human의 길이 값(구명보트를 혼자 또는 2명이서 같이 탈 수 있는 사람 수)을 더해서 return 해준다.
function solution(people, limit) {
var answer = 0;
people.sort((a, b) => a-b);
const human = people.filter(num => num <= limit-40);
const len = people.filter(num => num > limit-40).length;
for(let i=0; i<human.length; i++) {
for(let j=human.length-1; j>i; j--) {
if(human[i] + human[j] <= limit) {
human.splice(j, 1);
break;
}
}
}
answer += human.length + len;
return answer;
}
배열 people을 오름차순으로 정렬한다.
for 문을 돌리고 i=0, j=people.length-1 부터 시작하고 j를 i+1까지 1씩 줄인다.
people[i] 값과 people[j] 값을 더한 값이 limit보다 작거나 같다면 i를 1씩 증가시킨다.
people의 길이 값과 i를 뺀 값을 return 해준다.
people[i] + people[j] 가 limit보다 작거나 같다면 2명이서 구명보트 1개를 탈 수 있기 때문에 i를 1 증가시키고 for 문이 끝나면 people.length-i; 를 return 하는 것이다.
function solution(people, limit) {
people.sort(function(a, b){return a-b});
for(var i=0, j=people.length-1; i < j; j--) {
if( people[i] + people[j] <= limit ) i++;
}
return people.length-i;
}
for 문의 break;와 continue;에 대해서 다시 한 번 공부하게 되었다.
for(let i=0; i<human.length; i++) {
for(let j=human.length-1; j>i; j--) {
if(human[i] + human[j] <= limit) {
human.splice(j, 1);
// continue;
// i=0 일 때, 여기에서 continue를 하면 j의 감소를 멈추고
// i=1, j=human.length; 부터 다시 시작할 줄 알았다.
break;
}
}
}
이중 for 문에서 human[i] + human[j] <= limit 라면 human[j]의 값을 삭제하고 j의 감소를 막기 위해 continue;를 사용했는데, break;를 사용해야 i가 증가하면서 j가 다시 human.length; 값으로 초기화되었다.
분명히 공부했던 것임에도 불구하고 많이 헷갈리고 실전에 적용을 잘 못하는 것 같다. 하지만 이렇게 공부하면서 헷갈린 문법들을 차근차근 배워나가고 있다는 생각도 든다. 그리고 LV2는 아직 나한테는 많이 어려운 것 같다.. ㅎㅎ;