Remove Element

zoovely·2023년 6월 12일
0
post-thumbnail

💬 문제

[문제 링크]
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;
};

사실 여러 방법으로 풀어봤었는데, 결과가 가장 좋은 것 중 하나를 택했다.

  • forEach로 nums를 돌면서 val과 같은 값이면 null로 바꿔준다.
  • sort()한다. null은 숫자가 아니어서 맨 뒤로 가게 된다.
  • for문으로 배열을 뒤에서부터 돌면서 null일 경우 pop()으로 삭제 해준다. 만약 null이 아닌 값을 마주치면 종료한다.
  • null을 다 뺀 nums의 길이 반환

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문이 더 성능면에서 좋다는 이야기를 보았다. 해당 글은 자바를 사용하기도 했으니 도대체 어느게 맞는 건지는 직접 간단한 테스트를 통해 알아봐야 할 것 같다.

profile
나도 할 수 있을까?

0개의 댓글