1. 程式人生 > >【LeetCode】283. Move Zeroes

【LeetCode】283. Move Zeroes

283.Move Zeroes

Description:
Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements.
Difficulty:Easy
Example:

Input: [0,1,0,3,12]
Output: [1,3,12,0,0]

Note:

  • You must do this in-place without making a copy of the array.
  • Minimize the total number of operations.

方法1:空間次優

  • Time complexity : O ( n ) O\left ( n \right )
  • Space complexity : O ( n ) O\left ( n \right )
    思路

    將非零元素儲存在另一個數組裡,再將0填充在最後
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int n = nums.size();
		int num_zeroes = 0;
		vector<int> temp_vector;
		for (int i = 0; i < n; i++) {
			if (nums[i] == 0) {
				num_zeroes += 1;
			}
			else {
				temp_vector.push_back(nums[i]);
			}
		}
		while (num_zeroes--) {
			temp_vector.push_back(0);
		}
		for (int i = 0; i < n; i++) {
			nums[i] = temp_vector[i];
		}
    }
};

方法2:空間最優,運算元次優

  • Time complexity : O ( n ) O\left ( n \right )
  • Space complexity : O ( 1 ) O\left ( 1 \right )
    思路
    快慢指標,慢指標始終指向非零元素的後面一個位置,當快指標發現了非零元素,將非零元素賦值給慢指標,慢指標向後移一位。
    第一次遍歷,將所有非零元素移到陣列靠前部分;
    第二次遍歷,將慢指標後面的元素置0。
    關鍵點
    與方法1比較,利用覆蓋減少空間的使用。
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
		int last_non_zero_at = 0;
		for (int i = 0; i < nums.size(); i++) {
			if (nums[i] != 0) {
				nums[last_non_zero_at++] = nums[i];
			}
		}
		for (int i = last_non_zero_at; i < nums.size(); i++) {
			nums[i] = 0;
		}
    }
};

方法3:最優

  • Time complexity : O ( n ) O\left ( n \right )
  • Space complexity : O ( 1 ) O\left ( 1 \right )
    思路
    與方法2相似,但是不進行覆蓋而是交換,可以儘量減少操作次數,例如[0,0,…,0.1],在方法2中0會被寫很多次
    關鍵點
  • 保持陣列有三個區域,第一部分是非零元素,第二部分是零元素,第三部分是未判斷區域,慢指標指向零元素的第一個位置,快指標指向未判斷區域的第一個,如果發現非零元素,快慢指標交換
  • 可以不用交換操作,但要注意邊界,例如[1,1,1,1]
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
		int last_non_zero_at = 0;
		for (int i = 0; i < nums.size(); i++) {
			if (nums[i] != 0) {
				swap(nums[last_non_zero_at++], nums[i]);
			}
		}
    }
};