LeetCode

LZC發表於2021-04-25

26-刪除重複元素

給你一個有序陣列 nums ,請你 原地 刪除重複出現的元素,使每個元素 只出現一次 ,返回刪除後陣列的新長度。

不要使用額外的陣列空間,你必須在 原地 修改輸入陣列 並在使用 O(1) 額外空間的條件下完成。
連結:leetcode-cn.com/problems/remove-du...

class Solution {
    public int removeDuplicates(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }
        if (nums.length == 1) {
            return 1;
        }
        int slow = 1;
        int fast = 1;
        // 1 2 2 3
        while (fast < nums.length) {
            if (nums[fast] != nums[fast - 1]) {
                nums[slow] = nums[fast];
                slow++;
            } 
            fast++;
        }
        return slow;
    }
}

27-移除元素

給你一個陣列 nums 和一個值 val,你需要 原地 移除所有數值等於 val 的元素,並返回移除後陣列的新長度。

不要使用額外的陣列空間,你必須僅使用 O(1) 額外空間並 原地 修改輸入陣列。

元素的順序可以改變。你不需要考慮陣列中超出新長度後面的元素。
連結:leetcode-cn.com/problems/remove-el...

方法一:

    public int removeElement(int[] nums, int val) {
        // left代表下一個不等於val的下標
        int left = 0;
        // 遍歷陣列,只要不等於val的就賦值給num[left],同事left++
        for (int j = 0; j < nums.length; j++) {
            if (nums[j] != val) {
                nums[left] = nums[j];
                left++;
            }
        }
        return left;
    }

方法二:

/**
 * 元素的順序可以改變,所以可以使用兩個下標left、right
 * left從左向右尋找等於val的元素
 * right從右向左尋找不等於val的值
 * 最後令nums[right] = num[right]
 */
public int removeElement(int[] nums, int val) {
        int left = 0, right = nums.length - 1;
        int count = 0;
        while (left <= right) {
            while (left <= right && nums[left] != val && left < nums.length) {
                left++;
                count++;
            }
            while (left <= right && nums[right] == val && right >= 0) {
                right--;
            }
            if (left < right) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                count++;
                left++;
                right--;
            }
        }
        return count;
    }

方法三:

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

189-旋轉陣列

給定一個陣列,將陣列中的元素向右移動 k 個位置,其中 k 是非負數。

進階:

儘可能想出更多的解決方案,至少有三種不同的方法可以解決這個問題。
你可以使用空間複雜度為 O(1) 的 原地 演算法解決這個問題嗎?

示例 1:

輸入: nums = [1,2,3,4,5,6,7], k = 3
輸出: [5,6,7,1,2,3,4]
解釋:
向右旋轉 1 步: [7,1,2,3,4,5,6]
向右旋轉 2 步: [6,7,1,2,3,4,5]
向右旋轉 3 步: [5,6,7,1,2,3,4]
連結:leetcode-cn.com/problems/rotate-ar...

暴力法會超時

// 會超時
    public void rotate(int[] nums, int k) {
        k = k % nums.length;
        for (int i = 0; i < k; i++) {
            int last = nums[nums.length - 1];
            for (int j = nums.length - 1; j > 0; j--) {
                nums[j] = nums[j - 1];
            }
            nums[0] = last;
        }
    }

透過找規律可以發現,翻轉後的陣列,將前k個翻轉並且將剩下的(l-k)個也翻轉,最後得到的資料為原始陣列翻轉後的結果。

因此我們可以先把整個陣列翻轉,然後將k個元素翻轉,最後將後(l-k)個元素也翻轉

public void rotate(int[] nums, int k) {
        k = k % nums.length;
        fun(nums, 0, nums.length - 1);
        fun(nums, 0, k - 1);
        fun(nums, k, nums.length - 1);
    }
    public void fun(int[] nums, int left, int right) {
        while (left < right) {
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
            left++;
            right--;
        }
    }

300-最長遞增子序列

給你一個整數陣列 nums ,找到其中最長嚴格遞增子序列的長度。

子序列是由陣列派生而來的序列,刪除(或不刪除)陣列中的元素而不改變其餘元素的順序。例如,[3,6,2,7] 是陣列 [0,3,1,6,2,2,7] 的子序列。

連結:leetcode-cn.com/problems/longest-i...

class Solution {
    /**
     * dp[i] = max(dp[j] + 1, dp[i]), 0 <= j < i
     * [0,3,1,6,2,2,7]
     */
    public int lengthOfLIS(int[] nums) {
        if (nums.length == 1) {
            return 1;
        }
        int[] dp = new int[nums.length];
        dp[0] = 1;
        int max = 1;
        for (int i = 1; i < nums.length; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                // 找到比當前i的值小了
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[j] + 1, dp[i]);
                    max = Math.max(max, dp[i]);
                }
            }
        }
        return max;
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章