LeetCode—283—Move Zeroes
題目
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.
Example:
Input: [0,1,0,3,12]
Output: [1,3,12,0,0]
翻譯
給定一個陣列nums,寫一個函式,將陣列中所有的0元素,挪到陣列的末尾,而維持其他所有非0元素的相對位置。
舉例: [0,1,0,3,12],函式執行後結果為[1,3,12,0,0]
如何解決
(1)最直觀的思路
首先我們掃描一遍陣列,將所有非零元素全都拿出來。有幾個這樣的非零元素。就將這些元素填補到原先的陣列中。之後將沒填補的位置全都賦值為0;
取出所有非零元素
將非零元素填補到陣列中
將沒填補的位置全都賦值為0
程式碼如下:
import java.util.*;
// 283. Move Zeroes
// https://leetcode.com/problems/move-zeroes/description/
// 時間複雜度: O(n)
// 空間複雜度: O(n)
class Solution1 {
public void moveZeroes(int[] nums) {
ArrayList<Integer> nonZeroElements = new ArrayList<Integer>();
// 將vec中所有非0元素放入nonZeroElements中
for (int i = 0; i < nums.length; i++)
if (nums[i] != 0)
nonZeroElements.add(nums[i]);
// 將nonZeroElements中的所有元素依次放入到nums開始的位置
for (int i = 0; i < nonZeroElements.size(); i++)
nums[i] = nonZeroElements.get(i);
// 將nums剩餘的位置放置為0
for (int i = nonZeroElements.size(); i < nums.length; i++)
nums[i] = 0;
}
}
一級優化
上面這種解題方法雖然解決了問題。但是有沒有更好的解決方法呢,我們分析上面的這種解題思路,在上一個方法中我們新開闢了一片空間,用於儲存非零元素,所以他的空間複雜度為O(n),接下來這種解法,我們就用nums陣列本身來實現。
先看下面這張圖
在這裡我們新定義一個索引 k,在[0...k)這個前閉後開的區間中存放所有遍歷過的非0元素。我們開始遍歷陣列,當遍歷的元素是非零元素時,就將元素放在k所在的位置,同時為了存放下一個非0元素。k要加一,繼續遍歷陣列。
上圖中遍歷到第二個元素,為非0元素,所以要將1放到k所在的位置,此後k加一。
到我們遍歷完陣列時,此時區間[0...k)存放了所有非零元素,下來我們要做的就是從當前k開始,將剩餘所有元素都賦值為0,從而完成整個操作,此時整個操作的空間複雜度為O(1)級別。
程式碼如下:
// 原地(in place)解決該問題
// 時間複雜度: O(n)
// 空間複雜度: O(1)
class Solution2 {
public void moveZeroes(int[] nums) {
int k = 0; // nums中, [0...k)的元素均為非0元素
// 遍歷到第i個元素後,保證[0...i]中所有非0元素
// 都按照順序排列在[0...k)中
for(int i = 0 ; i < nums.length ; i ++)
if( nums[i] != 0 )
nums[k++] = nums[i];
// 將nums剩餘的位置放置為0
for(int i = k ; i < nums.length ; i ++)
nums[i] = 0;
}
}
二級優化
通過前面的優化雖然我們在原地完成了move zeros的操作。但是當我們將所有的非0元素都挪到陣列的前面時。我們還要花費一些操作,將剩餘元素全都賦值為0。那麼顯而易見的想法是將所有非零元素放好位置時,相應的0元素已經放在了後面。其實我們可以通過將非0元素和0元素交換位置,從而達到這個目的。
如上圖,此時遍歷到第四個元素,此時為非0元素。所以將第四個元素和k所在的元素交換位置,變成下面這幅圖,最終完成整個操作。
程式碼如下:
// 原地(in place)解決該問題
// 時間複雜度: O(n)
// 空間複雜度: O(1)
class Solution3 {
public void moveZeroes(int[] nums) {
int k = 0; // nums中, [0...k)的元素均為非0元素
// 遍歷到第i個元素後,保證[0...i]中所有非0元素
// 都按照順序排列在[0...k)中
// 同時, [k...i] 為 0
for(int i = 0 ; i < nums.length ; i ++)
if(nums[i] != 0)
swap(nums, k++, i);
}
private void swap(int[] nums, int i, int j){
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
最終優化
演算法的世界裡沒有最好,只有更好。在上面這個問題中,那麼有沒有一種可能就是nums陣列全是非零元素。那如果這樣的話。我們遍歷一遍,就相當於每個元素自己和自己交換了一遍位置。那麼這是我們不希望看到的。那麼在這裡我們還需要加入一個特殊的判斷。優化後的程式碼如下:
// 原地(in place)解決該問題
// 時間複雜度: O(n)
// 空間複雜度: O(1)
class Solution4 {
public void moveZeroes(int[] nums) {
int k = 0; // nums中, [0...k)的元素均為非0元素
// 遍歷到第i個元素後,保證[0...i]中所有非0元素
// 都按照順序排列在[0...k)中
// 同時, [k...i] 為 0
for(int i = 0 ; i < nums.length ; i ++)
if(nums[i] != 0)
if(k != i)
swap(nums, k++, i);
else
k ++;
}
private void swap(int[] nums, int i, int j){
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
更多內容歡迎大家關注
相關文章
- 283. Move Zeroes--LeetCode RecordLeetCode
- Lintcode539 Move Zeroes solution 題解
- LeetCode 283 jsLeetCodeJS
- Leetcode Set Matrix ZeroesLeetCode
- LeetCode 73 Set Matrix ZeroesLeetCode
- Leetcode-Set Matrix ZeroesLeetCode
- Set Matrix Zeroes leetcode javaLeetCodeJava
- Leetcode 73. Set Matrix ZeroesLeetCode
- leetcode_283. 移動零LeetCode
- leetcode 283. 移動零(簡單)LeetCode
- leetcode學習筆記73 Set Matrix ZeroesLeetCode筆記
- Leetcode 172. Factorial Trailing ZeroesLeetCodeAI
- leetcode刷題--Factorial Trailing ZeroesLeetCodeAI
- LeetCode每日一題: 移動零(No.283)LeetCode每日一題
- leetcode陣列練習題2:283. 移動零LeetCode陣列
- 每天一道LeetCode--172. Factorial Trailing ZeroesLeetCodeAI
- LeetCode # 283 陣列裡的0全都移到最後,其他保持原順序LeetCode陣列
- 演算法Set Matrix Zeroes演算法
- Move to GithubGithub
- 力扣-283. 移動零力扣
- move.jsJS
- [CareerCup] 1.7 Set Matrix Zeroes 矩陣賦零矩陣
- Oracle的move操作Oracle
- move表操作流程
- move oracle 10 directoryOracle
- Codeforces Round #283 (Div. 2) D,E
- oracle 分割槽表move和包含分割槽表的lob moveOracle
- Move_or_Rename_the_Tempfile_in_OracleOracle
- CopyMemory Move使用筆記筆記
- ORACLE MOVE表空間Oracle
- Move users between domainsAI
- Factorial Trailing Zeroes 階乘後的零AI
- alter table table_name move ; 在自身表空間move是如何操作的?
- Oracle 11G OCP 1Z0-053 283Oracle
- Move datafile:From File System to ASMASM
- Move datafile:From ASM to File SystemASM
- How to move progress database to different OSDatabase
- LeetCodeHot100 283. 移動零 11. 盛最多水的容器 42. 接雨水 15. 三數之和LeetCode