題目描述
給定一個陣列 nums,編寫一個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序。
請注意 ,必須在不復制陣列的情況下原地對陣列進行操作。
示例 1:
輸入: nums = [0,1,0,3,12]
輸出: [1,3,12,0,0]
示例 2:
輸入: nums = [0]
輸出: [0]
力扣原題目地址:https://leetcode.cn/problems/...
思路分析
解法一 遍歷統計0出現了幾次並刪除之,最後根據0出現的次數往尾部追加0
var moveZeroes = function (nums) {
let count = 0 // 1. 定義一個變數,用來統計0出現的次數
for (let i = 0; i < nums.length; i++) { // 2. 遍歷這個陣列,看看0出現了幾次
if (nums[i] == 0) { // 3. 如果遇到的不是0,不做任何操作;如果遇到0了,就把0刪掉
nums.splice(i, 1) // 4. 把遇到的這一項(0)給刪除掉
i-- // 5. 注意 陣列塌陷,索引統一往前平移一位
count = count + 1 // 6. 然後統計一下0出現的次數
}
}
for (let i = 0; i < count; i++) { // 7. 根據0出現的次數,決定往陣列的尾部追加幾個0
nums.push(0) // 8. 出現了幾個0,最後就追加幾個0,
}
};
這種方式,需要遍歷兩次,我們遍歷一次也是可以解決的,思路略有相似。如下程式碼
解法二 尾部追加一個結束項標識,遍歷遇到0刪除之
var moveZeroes = function (nums) {
nums.push('endFlag') // 1. 手動在陣列的最後,追加一項,用於判斷是否遍歷到最後的標識
for (let i = 0; i < nums.length; i++) { // 2. 遍歷這個陣列
// 3. 一開始肯定不是最後一項的標識,所以繼續往後看
if (nums[i] == 'endFlag') { // 8. 當遇到之前我們手動新增的'endFlag'標識的時候,就說明原來的陣列遍歷一遍了
nums.splice(i, 1) // 9. 最後再把之前手動新增的標識給刪掉就行啦,搞定
return
}
if (nums[i] === 0) { // 4. 當遇到0的時候做移動零操作
nums[nums.length] = 0 // 5. 先再陣列的最後的位置新增一個0
nums.splice(i, 1) // 6. 然後在把當前的0刪除掉,這樣也可以理解為移動0
i-- // 7. 注意陣列刪除掉一個元素以後,陣列的索引塌陷,後續的索引都會往前進一位,所以需要再統一扣除1位,以達到平衡
}
}
};
總結
在實際工作中,時間複雜度,要優先與空間複雜度,因為空間複雜度問題,多增加點記憶體就行了。但是時間複雜度,才是我們寫程式碼追求的極速目標。所以,能遍歷一次的,最好不要遍歷兩次。至於多定義幾個變數導致多用了一些記憶體,基本上可以忽略的