Hi 你們好,我是張小豬。歡迎來到『寶寶也能看懂』系列特別篇 - 30-Day LeetCoding Challenge。git
這是一個 leetcode 官方的小活動。能夠在官網看到,從 4 月 1 號開始,天天官方會選出一道題,在 24 小時內完成便可得到一點小獎勵。雖然獎勵彷佛也沒什麼用,不過做爲一個官方的打卡活動,小豬仍是來打一下卡吧,正好做爲天天下班回家後的娛樂。github
這裏是 4 月 4 號的題,也是題目列表中的第 283 題 -- 『移動零』shell
給定一個數組 nums,編寫一個函數將全部 0 移動到數組的末尾,同時保持非零元素的相對順序。segmentfault
示例:數組
輸入: [0,1,0,3,12] 輸出: [1,3,12,0,0]
說明:函數
EASYspa
這道題的核心要求在於須要作原地的賦值,不然咱們只須要建立一個新數組,而後根據遍歷的數值向裏 push
便可。指針
爲了作到原地,咱們便須要知道 0 值所在的下標位置,以及要替換成什麼值。基於這個思路,咱們很容易想到,能夠在遍歷的過程當中針對值是否爲 0 作區分處理。code
基於上面的思路,咱們能夠經過兩個指針來完整整個數組的遍歷。其中一個指針用於單純的做爲下標遞增,另一個指針用於標識當前還未被處理的 0 值的位置。blog
對於其它的非 0 值而言,兩個指針會同步移動。而遇到 0 的時候,用於特殊標識的指針便停下,直到遍歷的指針遇到一個非 0 的值,咱們將兩個值的位置進行交換,這樣便完成了一次 0 值向下一個非 0 值位置的移動。而咱們後續須要作的只是繼續重複這個過程,直到完成遍歷。這樣全部的 0 值就會被移動到末尾。
具體代碼以下:
const moveZeroes = nums => { for (let i = 0, zero = 0; i < nums.length; ++i) { if (nums[zero] === 0 && nums[i] !== 0) { nums[zero] = nums[i]; nums[i] = 0; } nums[zero] !== 0 && ++zero; } };
咱們能夠把 nums
數組想象成有兩個,一個是原始數組,一個是處理以後的數組。因而咱們用一個值來遍歷原始數組,而用另外一個值 idx
來標識數據在處理完以後的數組中的位置。
那麼在遍歷的過程當中,若是遇到 0 值,則 idx
不進行任何修改,而遇到非 0 值,則將其賦值給 idx
的位置,而且將 idx
進行後移。這樣遍歷完成後,咱們便處理完了全部非 0 值的正確位置。只須要再將後面的位置所有填充 0 值便可。
具體代碼以下:
const moveZeroes = nums => { let idx = 0; for (let i = 0; i < nums.length; ++i) { nums[i] !== 0 && (nums[idx++] = nums[i]); } while (idx < nums.length) nums[idx++] = 0; };
做爲『30-Day LeetCoding Challenge』的第四題,仍舊沒有什麼太多可說的。經過兩種思路來進行了分析,但願能幫到有須要的小夥伴。
若是以爲不錯的話,記得『三連』哦。小豬愛大家喲~