[문제 링크]
nums : int 배열
val : nums에서 뒤로 보내야 할 수
nums에 있는 val을 전부 뒤로 몰고, val이 아닌 nums 내 요소의 개수 k를 반환
in-place하게 이루어져야 함 (=자료구조를 추가로 사용하지 않고 입력값을 변환)
배열 내 요소의 순서는 달라져도 괜찮음
(아마도 k를 기반으로 바뀐 nums를 자르고 값이 다 들어있는지 보는 듯)
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
nums.forEach((num, idx) => {
if (num === val)
nums[idx] = null;
});
nums.sort();
let numlen = nums.length;
for (let i = numlen - 1; i >= 0; i--) {
if (nums[i] === null)
nums.pop();
else
break;
}
return nums.length;
};
사실 여러 방법으로 풀어봤었는데, 결과가 가장 좋은 것 중 하나를 택했다.
val 값을 뒤로만 몰면 되기 때문에 pop()은 안해도 상관 없었다. 그런데 왜인지 삭제를 안한 답변은 다 성능이 좋지 않았다. 내 알고리즘을 포함해 output을 뽑아 답을 확인하는 과정에서 배열이 짧은 것이 더 빠르기 때문이었을까?
Accepted
Runtime 48 ms (Beats 96.25%)
Memory 41.8 MB (Beats 69.63%)
var removeElement = function(nums, val) {
var j = 0;
for(var i=0;i<nums.length;i++) {
if(nums[i]!=val)
nums[j++] = nums[i];
}
return j;
};
beats 90~100%의 답안이다. 저번 문제와 비슷하게 값을 대입하는 방식으로, val과 같지 않은 값이면 앞으로 땡겨서 차곡차곡 쌓는 방법을 사용했다. 뒤의 값이 무엇이든 상관없고, k까지만 val과 같지 않은 nums 내의 값이면 되기 때문이다. 이 경우는 순서도 안바뀌고 sort()를 사용할 필요도 없어서 매우 좋은 것 같다. 이전에서도 한 방 먹어 놓고 이번에도 놓쳐버렸다...
var removeElement = function(nums, val) {
let k = 0;
nums.forEach((num, idx) => {
if (num === val)
nums[idx] = null;
else
k++;
});
nums.sort();
return k;
};
//Runtime 64ms (Beats 32.7%) Memory 42.6MB (Beats 8.55%)
var removeElement = function(nums, val) {
let k = 0;
const numlen = nums.length;
for (let i = 0; i < numlen; i++) {
if (nums[i] === val)
nums[i] = null;
else
k++;
}
nums.sort();
return k;
};
//Runtime 61ms (Beats 47.44%) Memory 42.3MB (Beats 30.90%)
이건 내가 시도했던 코드인데, 위는 forEach로 배열을 탐색하며 값을 바꾸고 아래는 for문으로 탐색하며 값을 바꿨다. 다른 점은 그 뿐인데 메모리 사용량 및 속도가 for문이 더 낫다! 통상적으로는 forEach가 훨씬 빠르고 효율적으로 배열을 탐색하는 것으로 알려져있는데, 이번을 계기로 찾아보니 배열에서는 for문이 더 성능면에서 좋다는 이야기를 보았다. 해당 글은 자바를 사용하기도 했으니 도대체 어느게 맞는 건지는 직접 간단한 테스트를 통해 알아봐야 할 것 같다.