1. 程式人生 > >LeetCode 題解之 283. Move Zeroes

LeetCode 題解之 283. Move Zeroes

283. Move Zeroes

題目描述和難度

  • 題目描述:

給定一個數組 nums,編寫一個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序。

示例:

輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]

說明:

  1. 必須在原陣列上操作,不能拷貝額外的陣列。
  2. 儘量減少操作次數。

思路分析

求解關鍵:這道題的寫法有 2 種,一種是沒有學習過演算法都很容易想到的,另一種其實只要演算法基礎紮實,也是非常容易想到的。

  • 思路1:遍歷一遍陣列,把非零值覆蓋在陣列的前面,最後在把陣列的末尾全部賦值為 0。

這個思路比較容易想到,但是隻要熟悉了快速排序,應該更容易想到下面的寫法。

  • 思路2(推薦):藉助快速排序 partition 的思想,遇到 0 就放過,遇到非 0 ,這是符合題目中“儘量減少操作次數”這個要求的。

就逐個交換到陣列的前面。更推薦使用這種寫法,簡潔。

在練習的時候,我還想到了“指標對撞”的思路,可以使得非零元素排在零元素前面,但是不能做到“保持非零元素的相對順序”。

參考解答

參考解答1

Java 寫法:

public class Solution {

    public void moveZeroes(int[] nums) {
        // 遍歷指標
        int i = 0;
        // 一開始都寫非零元素,然後都寫零元素
        int j = 0;
        for (; i < nums.length; i++) {
            if (nums[i] != 0) {
                nums[j++] = nums[i];
            }
        }
for (int k = j; k < nums.length; k++) { nums[k] = 0; } } }

Python 寫法:

class Solution:
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """

        not_zero_begin = 0

        for i in range(len(nums)):
            if nums[i] != 0:
                nums[not_zero_begin] = nums[i]
                not_zero_begin += 1

        for i in range(not_zero_begin, len(nums)):
            nums[not_zero_begin] = 0
            not_zero_begin += 1

參考解答2

Java 寫法:

public class Solution3 {

    // https://leetcode-cn.com/problems/move-zeroes/description/
    // [0, 1, 0, 3, 12]
    // [1, 0, 0, 3, 12]
    // [1, 3, 0, 0, 12]
    // [1, 3, 12, 0, 0]
    // 常規題:用思維定勢就可以完成
    /**
     * i 用於遍歷
     * 在區間 [0,j) 裡,所有的值都非零
     * 而在區間 [j,i) 裡,所有的值都為零
     * 初始化的時候 j = 0 , i = 0
     *
     * @param nums
     */
    public void moveZeroes(int[] nums) {
        int j = 0;
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]!=0){
                swap(nums,i,j);
                j++;
            }

        }
    }

    private void swap(int[] nums,int index1,int index2){
        if(index1==index2){
            return;
        }
        int temp = nums[index1];
        nums[index1] =nums[index2];
        nums[index2] = temp;
    }
}

Python 寫法:

class Solution:

    # 快速排序的方法,最簡單,最直接

    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """

        # [0,not_zero_end) 保持都非 0,
        # [not_zero_end,len-1] 為 0
        not_zero_end = 0

        for i in range(len(nums)):
            if nums[i] != 0:
                self.__swap(nums, not_zero_end, i)
                not_zero_end += 1

    def __swap(self, nums, index1, index2):
        if index1 == index2:
            return
        temp = nums[index1]
        nums[index1] = nums[index2]
        nums[index2] = temp

Python 寫法:

class Solution:

    # 快排實現:
    # Python 交換陣列中的元素,可以用 Python 特殊的語法實現

    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """

        not_zero_end = 0  # 不包括末尾元素
        for j in range(len(nums)):
            if nums[j] != 0:
                nums[not_zero_end], nums[j] = nums[j], nums[not_zero_end]
                not_zero_end += 1

本篇文章的地址為 https://liweiwei1419.github.io/leetcode-solution/leetcode-0283-move-zeroes ,如果我的題解有錯誤,或者您有更好的解法,歡迎您告訴我 [email protected]