코딩테스트
[릿코드/js] 다시풀기 137.candy
_서리__
2023. 9. 13. 16:23
var candy = function(ratings) {
//일단 하나씩 할당하고,
//재귀를 통해 이웃이랑 비교하면서 하나씩 추가하면됨. 와일로도 가능할듯?
let child = new Array(ratings.length).fill(1);
while(!is_correct(ratings,child))
{
const len = child.length;
for (let i = 0; i < len; i++)
{
if (i - 1 >= 0)
{
if (ratings[i - 1] < ratings[i] && child[i - 1] >= child[i])
{
child[i] = child[i - 1] + 1;
};
}
if (i + 1 <= len)
{
if (ratings[i] > ratings[i + 1] && child[i] <= child[i + 1])
{
child[i] = child[i + 1] + 1;
};
}
}
}
return child.reduce((acc,cur) => acc + cur);
};
let is_correct = function(ratings, child)
{
const len = child.length;
for (let i = 0; i < len; i++)
{
if (i - 1 >= 0)
{
if (ratings[i - 1] < ratings[i] && child[i - 1] >= child[i])
{
return false;
};
}
if (i + 1 <= len)
{
if (ratings[i] > ratings[i + 1] && child[i] <= child[i + 1])
{
return false;
};
}
}
return true;
}
-> 나의 풀이
ratings와 child 배열을 두고 child의 배열이 조건에 맞는지 확인하면서 while문을 돌린다. 이 while문 안에서 양쪽 조건을 동시에 확인함.
하지만 이렇게 하면 while문을 굉장히 많이 돈다는 단점이 있다.
(시간이 느림. 기본적으로 3중 while문인데다가 안에 조건도 몇개나 있다.)
var candy = function(ratings) {
//일단 하나씩 할당하고,
//재귀를 통해 이웃이랑 비교하면서 하나씩 추가하면됨. 와일로도 가능할듯?
let child = new Array(ratings.length).fill(1);
const len = child.length;
for (let i = 1; i < len; i++)
{
if (ratings[i - 1] < ratings[i])
{
child[i] = child[i - 1] + 1;
};
}
for(let i = len - 2; i >= 0; i--)
{
if (ratings[i] > ratings[i + 1])
{
if (child[i] <= child[i + 1]) child[i] = child[i + 1] + 1;
}
}
return child.reduce((acc,cur) => acc + cur);
};
-> 다른 이의 풀이를 참고하여 수정한 풀이
일단 for문을 돌려서 왼쪽이랑만 비교하여 child배열을 할당한다.
이후 다시 역방향으로 for문을 돌려서 오른쪽을 비교한다.
(이미 왼쪽은 할당이 되어있는상태임)
오른쪽 ratings보다 더 큰지 확인하고, 더 크다면 child[i]도 오른쪽보다 큰지 확인한다. 그렇다면 바꿀 이유가 없고,
그렇지 않다면 오른쪽것보다 +1을 해서 변경을 해준다. 그러면 오른쪽에서도 맞출 수 있다.
내가 걱정됐던건 이렇게 다시바꾸면서 왼쪽이랑 비교한 것이 틀어지지 않느냐 하는것이었는데...
1. 현재 값이 왼쪽보다 작거나 같은 경우에 교체할때.
오른쪽값+1이 현재값이 됨. (그럼 왼쪽값보다 더 커질 수 있다는 뜻.)
그럼 그 다음에 비교할때 수정이 됨.
그 다음 비교에서는 왼쪽값이 더 작으니까 현재값의 +1이 될것임,
2. 현재값이 왼쪽보다 큰 경우에 교체할때.
-> 문제 없음 ( 더 커지는 거니까.)
var candy = function(ratings) {
let child = new Array(ratings.length).fill(1);
const len = child.length;
for (let i = 1; i < len; i++)
{
if (ratings[i - 1] < ratings[i])
{
child[i] = child[i - 1] + 1;
};
}
for(let i = len - 2; i >= 0; i--)
{
if (ratings[i] > ratings[i + 1])
{
child[i] = Math.max(child[i], child[i + 1] + 1);
}
}
return child.reduce((acc,cur) => acc + cur);
};
gpt는 이렇게 푸는 것이 좀더 안정적이라고 한다 이유는 사실 잘 모르겠다. (정수만 들어오는 경우에 값은 똑같을것같음.)