JS解決數組算法的初始定義

移動零

給定一個數組 nums,編寫一個函數將所有0移動到數組的末尾,同時保持非零元素的相對順序。必須在原數組上操作,不能拷貝額外的數組。儘量減少操作次數。

示例:

輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]
  • 按順序複製非零元素到原數組中,空位補零
//執行用時 :64 ms, 在所有 javascript 提交中擊敗了97.33%的用戶
//內存消耗 :35.8 MB, 在所有 javascript 提交中擊敗了26.23%的用戶
var moveZeroes = function (nums) {
  let count = 0;
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] === 0) {
      nums.splice(i, 1);
      count++;
      i--;
    }
  }
  //填充count個0到末尾
  while (count-- != 0) {
    nums.push(0)
  }
};

//執行用時 :72 ms, 在所有 javascript 提交中擊敗了83.12%的用戶
//內存消耗 :35.8 MB, 在所有 javascript 提交中擊敗了24.65%的用戶
var moveZeroes = function (nums) {
  let len = nums.length;
  for (let i = 0; i < len; i++) {
    if (nums[i] === 0) {
      nums.push(nums.splice(i, 1))  
      len--;
      i--;
    }
  }
  return nums;
};
  • 不消耗額外空間,即空間複雜度在O(1),可以使用經典的雙指針解決。快指針尋找非0元素,慢指針填充元素,最後慢指針將剩餘的位置全部填充爲0
//執行用時 :80 ms, 在所有 javascript 提交中擊敗了47.43%的用戶
//內存消耗 :36.2 MB, 在所有 javascript 提交中擊敗了7.04%的用戶
var moveZeroes = function (nums) {
  var i = 0, j = 0;
  for (; j < nums.length; j++) {
    if (nums[j] !== 0) {
      nums[i] = nums[j];
      i++;
    }
  }
  for (; i < j; i++) {
    nums[i] = 0;
  }
  return nums;
};

  • 記錄0的位置,遇到非0交換
//執行用時 :76 ms, 在所有 javascript 提交中擊敗了66.19%的用戶
//內存消耗 :36.2 MB, 在所有 javascript 提交中擊敗了7.04%的用戶
var moveZeroes = function (nums) {
  let n = 0,
    index = 0;
  for (let i = 0; i < nums.length; ++i) {
    if (nums[i] == 0) {
      n++;
      if (n == 1) {
        index = i;
      }
    } else if (n > 0) {
      nums[index] = nums[i];
      nums[i] = 0;
      index = index + 1;
    }
  }
}

移動元素

給定一個數組 nums和一個值val,你需要原地移除所有數值等於val的元素,返回移除後數組的新長度。不要使用額外的數組空間,你必須在原地修改輸入數組並在使用O(1)額外空間的條件下完成。元素的順序可以改變。你不需要考慮數組中超出新長度後面的元素。

示例:

給定 nums = [0,1,2,2,3,0,4,2], val = 2,

函數應該返回新的長度 5, 並且 nums 中的前五個元素爲 0, 1, 3, 0, 4。

注意這五個元素可爲任意順序。

你不需要考慮數組中超出新長度後面的元素。

請注意,輸入數組是以“引用”方式傳遞的,這意味着在函數裏修改輸入數組對於調用者是可見的。
  • 複製到原數組定義 nums[0…i] 爲非 val 的數列,遍歷整個數列不斷的維護這個定義
//執行用時 :64 ms, 在所有 javascript 提交中擊敗了77.37%的用戶
//內存消耗 :34.2 MB, 在所有 javascript 提交中擊敗了5.58%的用戶
var removeElement = function (nums, val) {
  let j = 0;
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] != val) {
      nums[j] = nums[i];
      j++;
    }
  }
  return j;
};

  • 切割或添加元素到原數組
//執行用時 :64 ms, 在所有 javascript 提交中擊敗了77.37%的用戶
//內存消耗 :34.4 MB, 在所有 javascript 提交中擊敗了5.04%的用戶
var removeElement = function (nums, val) {
  var lang = nums.length;
  for (var i = 0; i < lang; i++) {
    if (nums[i] == val) {
      nums.splice(i, 1);
      i--;
    }
  }
  return nums.length;
};


//執行用時 :72 ms, 在所有 javascript 提交中擊敗了37.31%的用戶
//內存消耗 :34.4 MB, 在所有 javascript 提交中擊敗了5.04%的用戶
var removeElement = function (nums, val) {
  var len = nums.length;
  for (var i = len; i--;) {
    if (nums[i] !== val) {
      nums.push(nums[i]);   //nums.unshift(nums[i]); i++; j++;
    }
  }
  return nums.splice(0, len).length;
};

刪除排序數組中的重複項

給定一個排序數組,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後數組的新長度。不要使用額外的數組空間,你必須在原地修改輸入數組並在使用 O(1) 額外空間的條件下完成。

示例:

給定數組 nums = [1,1,2], 

函數應該返回新的長度 2, 並且原數組 nums 的前兩個元素被修改爲 1, 2。 

你不需要考慮數組中超出新長度後面的元素。

  • 定義 nums[0…i] 爲爲非重複數列,遍歷整個數列不斷的維護這個定義。解題思路與上題類似,判斷條件有改變
//執行用時 :76 ms, 在所有 javascript 提交中擊敗了94.62%的用戶
//內存消耗 :37.1 MB, 在所有 javascript 提交中擊敗了44.02%的用戶
var removeDuplicates = function (nums) {
  let j = 0;
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] != nums[i + 1]) {
      nums[j] = nums[i];
      j++;
    }
  }
  return j;
};


//執行用時 :84 ms, 在所有 javascript 提交中擊敗了77.86%的用戶
//內存消耗 :37.1 MB, 在所有 javascript 提交中擊敗了45.84%的用戶
var removeDuplicates = function (nums) {
  let len = nums.length;
  if (len < 2) { return len; }
  let i = 0;
  let j = i + 1;
  while (j <= len - 1) {
    if (nums[j] != nums[i]) {
      if (i + 1 != j) nums[i+1] = nums[j];
      i += 1;
    }
    j += 1;
  }
  return i + 1;
}

刪除排序數組中的重複項 II

給定一個排序數組,你需要在原地刪除重複出現的元素,使得每個元素最多出現兩次,返回移除後數組的新長度。不要使用額外的數組空間,你必須在原地修改輸入數組並在使用 O(1) 額外空間的條件下完成。

示例:

給定 nums = [1,1,1,2,2,3],

函數應返回新長度 length = 5, 並且原數組的前五個元素被修改爲 1, 1, 2, 2, 3 。

你不需要考慮數組中超出新長度後面的元素。
  • 判斷左右元素是否相同
//執行用時 :64 ms, 在所有 javascript 提交中擊敗了99.76%的用戶
//內存消耗 :36 MB, 在所有 javascript 提交中擊敗了35.71%的用戶
var removeDuplicates = function (nums) {
  let len = nums.length;
  if (len <= 2) return len;
  let i = 1;
  let j = i - 1;
  let k = i + 1;

  while (k <= len - 1) {
    if (nums[i] != nums[k] || (nums[i] == nums[k] && nums[j] != nums[k])) {
      j = i;
      nums[i + 1] = nums[k];
      i += 1;
    }
    k++;
  }
  return i + 1;
};

//js 兩邊與中間相等, 則刪除中間的
//執行用時 :84 ms, 在所有 javascript 提交中擊敗了53.28%的用戶
//內存消耗 :36 MB, 在所有 javascript 提交中擊敗了34.28%的用戶
var removeDuplicates = function (nums) {
  for (var i = 1; i < nums.length - 1; i++) {
    if (nums[i] == nums[i - 1] && nums[i] == nums[i + 1]) {
      nums.splice(i, 1);
      i--;
    }
  }
};

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/remove-element

發佈了54 篇原創文章 · 獲贊 13 · 訪問量 9148
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章