본문 바로가기

Algorithm

[LeetCode] Move Zeroes

문제 

Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements. Note that you must do this in-place without making a copy of the array.

 

주어진 숫자 배열에서 0을 찾아 모두 지우고 배열 맨 마지막으로 이동시켜라. 

배열의 복사본을 만들지 말고 주어진 배열 nums 안에서 해결할 것.

 

Follow up: Could you minimize the total number of operations done?

 

풀이 

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    
    if (nums.length === 0 && nums[0] == 0) return nums;
    
    let zero = [];
    
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] === 0) {
            nums.splice(i,1);
            zero.push(0);
            i--;
        } 
    }
    
    nums.push(...zero);
    
    return nums
    
};

nums에 0 하나만 들어있는 경우와 그렇지 않은 경우로 나누어 생각하고 코드를 작성하였다. for문을 돌려서 배열에서 0을 발견하면 배열 zero에 모아주었고, 0을 빼면서 -1 된 배열의 길이를 고려하여 마지막에 i--;를 해주었다. 0이 빠진 nums와 0을 모아둔 배열 zero 합쳐 return. 

 

통과는 했지만, 썩 매력적이지 않은 결과에 다시금 문제를 읽어 보았고.'Follow up: Could you minimize the total number of operations done?'라는 문장이 눈에 들어왔다. 

 

다른 풀이

var moveZeroes = function(nums) {
    let left = 0;
    
    for (let right = 0; right < nums.length; right++) {
        if (nums[right] !== 0) {
            // Swap non-zero element to the left side
            [nums[left], nums[right]] = [nums[right], nums[left]];
            left++;
        }
    }
};

chatGpt의 답안은 2개의 포인터를 사용하는 방법으로, right 포인터가 0이 아닌경우 왼쪽으로 옮겨준다.

 

다른풀이 

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let lastNonZeroPos = 0;
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            nums[lastNonZeroPos] = nums[i];
            lastNonZeroPos++;
        }
    }
    for (let i = lastNonZeroPos; i < nums.length; i++) {
        nums[i] = 0;
    }
};