前端與算法 leetcode 283. 移動零

# 前端與算法 leetcode 283. 移動零

題目描述

給定一個數組 nums,編寫一個函數將全部 0 移動到數組的末尾,同時保持非零元素的相對順序。前端

示例:java

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

說明:git

  1. 必須在原數組上操做,不能拷貝額外的數組。
  2. 儘可能減小操做次數。

283. 移動零github

概要

這個問題屬於 「數組變換」 的一個普遍範疇。這一類是技術面試的重點。主要是由於數組是如此簡單和易於使用的數據結構。遍歷或表示不須要任何樣板代碼,並且大多數代碼將看起來像僞代碼自己。[[1]]面試

問題的要求很簡單,將全部0移動到數組末尾且非0元素必須保持其原始順序算法

提示

雙指針,暴力法數組

解析

有意思的是,正常設計的算法,在遇到[0,0,0,0,1],[1,0,0,0,0,1]這兩種數組的時候都比較尷尬,沒辦法有效的減小操做次數,這兩個需求是相互排斥的,可是咱們能夠儘量的在其中找到平衡數據結構

解法一:暴力法

暴力法使用一個額外的數組,先將全部非0元素按照原順序push到數組裏同時用count統計0出現的次數,而後在額外的數組裏再pushcount個0,按照題目的要求咱們須要在原來的數組上改動,因此再依次將數組元素填入原數組函數

解法二:雙指針法

前一種方法有一些額外的操做.例如,全部(除最後一個)前導零的數組:[0,0,0,1]就會對數組進行許多沒必要要的操做,若是隻固定非0元素的話,能夠只交換一次

算法

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function (nums) {
  // 雙指針法
  for (let [i, j] = [0, 0]; i < nums.length; i++) {
    if (nums[i] !== 0) {
      [nums[j], nums[i]] = [nums[i], nums[j]]
      j++
    }
  }
  // 暴力法
  // let count = 0 // 統計0的個數
  // const res = [] // 返回的數組
  // nums.forEach(el => el === 0 ? count++ : res.push(el))
  // for (let i = 0; i < count; i++) {
  //   res.push(0)
  // }
  // for (let i = 0; i < nums.length; i++) {
  //   nums[i] = res[i]
  // }
}

傳入[0,1,0,3,12]的運行結果

[1,3,12,0,0]

執行結果

執行用時 :68 ms, 在全部 javascript 提交中擊敗了95.54%的用戶
內存消耗 :37.2 MB, 在全部 javascript 提交中擊敗了5.10%的用戶

GitHub倉庫

350. 兩個數組的交集 II [1]:https://leetcode-cn.com/problems/move-zeroes/solution/yi-dong-ling-by-leetcode/

相關文章
相關標籤/搜索