1. 程式人生 > >Java&LeetCode 初入門——027. 移除元素

Java&LeetCode 初入門——027. 移除元素

Java&LeetCode 初入門——027. 移除元素


本題與026題相似,是關於雙指標陣列的問題
文內程式碼全部採用JAVA語言。

題目

給定一個數組 nums 和一個值 val,你需要原地移除所有數值等於 val 的元素,返回移除後陣列的新長度。
不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 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。
注意這五個元素可為任意順序。
你不需要考慮陣列中超出新長度後面的元素。

個人解法

這裡採用的是和026相類似的雙指標法,指標 i 的方向是—>—>—>—>,從陣列起始位開始,指標 j 的方向是<—<—<—<— ,從陣列最末位開始。當i==j時,說明完全遍歷了整個陣列。

之所以產生這樣的想法,是因為每當查出一個目標值,這個值就需要被陣列中的其他非目標值替換。而新陣列的輸出值取決於新陣列的長度。如果我們不能將陣列尾端的非目標值前移,那麼就會失去這些值。。

先從 i 開始判斷,如果 i 位置的值是目標元素val,那麼就需要檢查j位置,如果 j 位置是非目標元素,則陣列長度+1,並用 j 位置的元素取代 i 位置的元素,這樣就刪除了 i 位置的值,並按預定次序移動i j的位置。如果如果 j 位置也是目標元素,就向前移動 j 直到 j 位置是非目標元素。

囉裡吧嗦,核心思想就是用陣列尾端的非val,替換陣列前端的val,每檢測到一個非val,新陣列長度+1。

執行用時: 9 ms, 在Remove Element的Java提交中擊敗了67.17% 的使用者

class Solution {
    public int removeElement(int[] nums, int val) {
		int i=0;
		int j=nums.length-1;
		int length=0;
		while (i<=j) {
			if (nums[i]==val) {
				if (nums[j]==val) {
					j--;
				}
				else {
					nums[i]=nums[j];
					j--;
					length++;
					i++;
				}
			}
			else {
				i++;
				length++;
			}
			
		}
		return length;
	}
}



官方解法

方法一

思路

既然問題要求我們就地刪除給定值的所有元素,我們就必須用 O(1) 的額外空間來處理它。如何解決?我們可以保留兩個指標 i 和 j,其中 i 是慢指標,j 是快指標。
其實和個人解法差不多,只是 i 和 j 有相同的起始位置,j 跑得快,一旦檢測到非val就覆蓋 i 。程式簡短,不錯不錯。執行時間和個人解法一樣,都是9ms。

演算法

在這裡插入圖片描述

public int removeElement(int[] nums, int val) {
    int i = 0;
    for (int j = 0; j < nums.length; j++) {
        if (nums[j] != val) {
            nums[i] = nums[j];
            i++;
        }
    }
    return i;
}

方法二

思路

在這裡插入圖片描述
這個想法好像和個人解法差不多,都是雙向來看,但是他不需要分為情況討論,所以程式碼顯得簡潔。
避免if語句的方法就是,把尾部的資料複製到前面之後,繼續檢查被取代的元素位置,直到符合要求。
時間同樣是9ms。

演算法

在這裡插入圖片描述

public int removeElement(int[] nums, int val) {
    int i = 0;
    int n = nums.length;
    while (i < n) {
        if (nums[i] == val) {
            nums[i] = nums[n - 1];
            // reduce array size by one
            n--;
        } else {
            i++;
        }
    }
    return n;
}