문제를 보자
푸드파이터 대회를 열었는데 대결방식은 1대 1이다.
매 대결마다 음식의 종류와 양이 바뀌고 준비된 음식을 일렬로 배치한 뒤
한 명은 왼쪽부터 다른 한명은 오른쪽부터 음식을 순서대로 먹는 방식이다.
가운데에 물을 놓고 물을 먼저 마시는 사람이 승리한다.
대회의 공정성을 위해 먹는 음식과 종류, 양이 같아야 하고 먹는 순서도 같아야 한다
이번 대회부터는 칼로리가 낮은 음식을 먼저 먹을 수 있게 배치해서 선수들이 음식을 더 잘 먹을 수 있게 하려고 한다
대회의 조건에 맞지 않은 음식을 가져오면 사용하지 못한다.
예를 들어 칼로리가 적은 순으로 1번 음식 3개, 2번 음식 4개, 3번 음식 6개를 준비했고 물을 0번이라 했을 때
두 선수는 1번 1개, 2번 2개, 3번 3개를 각각 먹으니 음식의 배치는 '1223330333221'이 된다.
홀수의 음식은 공평하게 나누지 못하니 1개를 사용하지 못한다.
칼로리가 적은 순서대로 나타내는 배열 food가 주어졌을 때 대회를 위한 음식의 배치를 나타내는 문자열을 return해라
라는 문제이다.
문제를 읽어보고 하나씩 생각해 보면 주어지는 것은 배열의 형태이고 반환하는 것은 문자열이다.
또 배열은 작은 칼로리부터 오름차순으로 정렬이 되어있고 배열의 [0]은 물로 정해서 항상 1이다.
내가 문제를 푼 풀이법이다.
function solution(food) {
var answer = '';
let reverseAnswer = '';
for(let i = 1;i <food.length;i++){
if(food [i]%2 === 1){
food[i] = food [i]-1;
}
for(let j = 0;j<(Math.floor(food [i]/2));j++){
answer += i
}
}
reverseAnswer = answer.split(""). reverse(). join("");;
answer += 0
answer += reverseAnswer
return answer;
}
하나씩 해석해 보자면
return 할 문자열 answer을 선언했고
거꾸로 뒤집은 문자열을 받을 reverseAnswer도 선언했다.
배열의 [0]은 항상 1이므로 제외하고 배열의 [1] 번부터 배열의 길이까지 반복을 한다.
만약 값이 홀수라면 공평하게 나누지 못하므로 1을 뺀다.
다시 반복문을 돌릴 건데 둘에게 공평하게 나누어야 하고 음식 개수마다 하나씩 문자열로 저장해야 하니
j=0부터 시작하고 각 배열의 자릿수를 2로 나누고 정수형으로 변환 한 값까지 반복을 한다.
그러면 answer에는 food [1]의 값만큼 반복하면서 answer에 더해질 것이고
반복을 다하면 절반은 완성이 된다.
예를 들어 배열이 [1,3,4,6]으로 들어왔다면
먼저 홀수를 처리해 줘서 [1,2,4,6]이 되고
각 배열값/2만큼 answer에 더해주니
'122333'이 answer에 저장되어 있다.
이건 왼쪽 사람 식탁에 준비된 것이고 오른쪽 사람에게 대칭으로 또 준비해야 한다.
그래서 answer을 split()으로 배열로 쪼개고 그 배열을 reverse()로 반대로 뒤집고 다시 join()으로 합쳐준다.
그 값을 reverseAnswer에 저장하면 안에 333221이 저장된다.
이제 다 왔다.
answer과 reverseAnswer을 더해주기만 하면 되는데 중앙에 물을 놓아야 한다.
그러므로 먼저 answer에 0을 더하고 그다음에 reverseAnswer을 더하면 '1223330333221'이 된다.
이 풀이는 이중 반복을 사용하기 때문에 시간복잡도가 크기 때문에 그렇게 효율적인 해결방식은 아니지만
내가 생각해 낼 수 있는 최선의 방법이었다..