來源:力扣(LeetCode) 連接:https://leetcode-cn.com/problems/remove-elementjavascript
給定一個數組 nums 和一個值 val,你須要原地移除全部數值等於 val 的元素,返回移除後數組的新長度。java
不要使用額外的數組空間,你必須在原地修改輸入數組並在使用 O(1) 額外空間的條件下完成。數組
元素的順序能夠改變。你不須要考慮數組中超出新長度後面的元素。函數
示例 1: 給定 nums = [3,2,2,3], val = 3, 函數應該返回新的長度 2, 而且 nums 中的前兩個元素均爲 2。 你不須要考慮數組中超出新長度後面的元素。
示例 2: 給定 nums = [0,1,2,2,3,0,4,2], val = 2, 函數應該返回新的長度 5, 而且 nums 中的前五個元素爲 0, 1, 3, 0, 4。 注意這五個元素可爲任意順序。 你不須要考慮數組中超出新長度後面的元素。
說明:性能
爲何返回數值是整數,但輸出的答案是數組呢?優化
請注意,輸入數組是以「引用」方式傳遞的,這意味着在函數裏修改輸入數組對於調用者是可見的。指針
你能夠想象內部操做以下:code
// nums 是以「引用」方式傳遞的。也就是說,不對實參做任何拷貝 int len = removeElement(nums, val); // 在函數裏修改輸入數組對於調用者是可見的。 // 根據你的函數返回的長度, 它會打印出數組中該長度範圍內的全部元素。 for (int i = 0; i < len; i++) { print(nums[i]); }
題解:ip
這條題目標識簡單,我初看的時候也沒很仔細看題,看了個大概,就立馬寫下內存
var removeElement = function(nums, val) { return nums.filter(item => item !== val); }
而後很快的運行代碼,發現跟我想要的結果不同,出來的結果徹底不對。而後我就轉頭開始審題了。。但願你們不要跟我犯同樣的錯誤。要仔細審題。
這裏着重兩個字:原地。須要原地移除。然而js中的刪除以後數組長度並不會變化。因此只能默默地看提示。
提示一:嘗試雙指針法。 提示二:你是否使用「元素順序能夠更改」這一屬性? 提示三:當要刪除的元素不多時會發生什麼?
以前幾個問題中都有涉及到雙指針,因而二話不說,就先聲明兩個指針。
var removeElement = function(nums, val) { //排除特殊狀況,數組長度爲1的時候 if(nums.length == 1 && nums[0] == val){ nums.pop(); return nums.length } //聲明雙指針 let left = 0,right = nums.length-1; while(left <= right){ if(nums[left] === val){ //當數組元素值爲val的時候,用右邊的值替代當前值,而且把右邊的值刪掉,以後移動指針 nums[left] = nums[right]; nums.pop(); right--; }else{ //當數組元素值不爲val的時候,移動左邊的指針 left++; } } return nums.length };
行雲流水得寫了一堆代碼,運行通了,提交以後也經過
執行用時 :56 ms, 在全部 javascript 提交中擊敗了99.04% 的用戶 內存消耗 :33.5 MB, 在全部 javascript 提交中擊敗了75.54%的用戶
看着還行,看看還能不能優化一下。畢竟少一個判斷的話會不會更好呢。
新思路:
聲明一個變量i=0;而後遍歷數組,若是值不等於val,就把這個值給nums[i],而後i++;這麼下來,i就是數組長度了
var removeElement = function(nums, val) { let i = 0 for (let j in nums) { if (nums[j] !== val) { nums[i] = nums[j]; i++; } } return i };
執行用時 :64 ms, 在全部 javascript 提交中擊敗了93.57% 的用戶 內存消耗 :33.7 MB, 在全部 javascript 提交中擊敗了35.08%的用戶
代碼量少了,用時卻多了,性能也不如以前,可是一樣的代碼會有不一樣的結果,我以爲第二種代碼少的畢竟簡單明瞭。不過對於其餘人可能就見仁見智了。
看了大佬的題解以後知道了,第一種方法可能移除較多元素畢竟合適,第二種移除較少的元素畢竟合適。