天天看點

Leetcode26-28,這幾道簡單有趣的算法題你都會嗎?

26-删除排序數組中的重複項

題目要求:

給定一個

排序數組

,你需要在

原地

删除重複出現的元素,使得每個元素隻出現一次,傳回移除後數組的新長度。

不要使用額外的數組空間,你必須在

原地修改輸入數組

并在使用

O(1)

額外空間的條件下完成。

示例1:

給定數組	nums = [1,1,2]
函數應該傳回新的長度 2 ,并且原數組nums的前兩個元素被修改為1,2
你不需要考慮數組中超出新長度後面的元素。
           

示例2:

給定數組	nums = [0,0,1,1,1,2,2,3,3,4]
函數應該傳回新的長度 5,并且原數組nums的前五個元素被修改為 0,1,2,3,4
你不需要考慮數組中超出新長度後面的元素
           

來簡單分析一下這道題,首先數組是排過序的,也就是說我們不需要用别的什麼花裡胡哨的算法,隻需要對數組周遊一下就行。

然後需要在

原地

删除重複出現的元素,同時不能使用額外的數組空間,這個是什麼意思呢?其實也就是說,你不能建立一個數組,然後在周遊的時候發現不同的數就給放入新數組。這樣的話就不是對原數組進行修改了,而且還用了額外的新空間。

我們知道數組是

引用資料類型

,也就是說我們對傳入的數組做任何改變都會直接移植到原數組,那麼我們需要做的就是直接對原數組操作就行了。

同時還有最後一個特别重要的條件:

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

。哎,這句話什麼意思?其實這句話就向我們提供了一種思路:

雙指針

。為什麼會這麼想?注意題目中要求是在

原地删除

元素,我們剛開始想的重點可能都是怎麼把元素删除,當我們不需要考慮超出新長度後面的元素的時候,我們就可以直接對原數組修改就行了,不需要把數組中的元素删除。

實作思路

雙指針,一個指針用來周遊原數組,找到不同的元素,另一個指針用來

修改

數組。周遊數組的指針是較快的指針,修改數組的指針是較慢的指針,當快的指針找到一個不重複的元素的時候,慢指針向前一位,然後修改該位的元素為快指針發現的不重複元素。

代碼(Java):

public int removeDuplicates(int[] nums) {
    int i = 0;	//i 慢指針  j 快指針
    for (int j = 1; j< nums.length; j++) {
        if (nums[i] != nums[j]) {
            i++;
            nums[i] = nums[j];
        }
    }
    return i+1;
}
           

代碼(Python):

def removeDuplicates(nums):
        nums[:] = sorted(set(nums))
        return len(nums)
           

嘿嘿,Python沒有用和Java相同的思路寫了,如果想實作相同思路,大家自己可以試着寫一下。咱們來分析一下如上的代碼。

因為Python有個資料類型叫

集合

,隻要

set()

一下,清單中的元素就不相同了,同時因為集合具有無序的特性,就用

sorted()

給去重後的集合排個序。那有同志可能要說了,為什麼不直接一行代碼:

return len(sorted(set(nums)))

搞定,還得切個整個集合的片?

因為leetcode有要求嘛,需要在原地删除元素,也就是說,對引用的數組做操作,而在leetcode的代碼框裡面是這樣的:

class Solution(object):
    def removeDuplicates(self, nums):
        nums[:] = sorted(set(nums))
        return len(nums)
           

也就是說,這是類的一個方法,如果在類中你寫一個nums變量,那它隻是一個新變量,并不是方法傳入的那個nums,是以最後傳回的長度隻是那個新變量的長度,而不是原數組的長度。

27-移除元素

題目要求:

給你一個數組 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。

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

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

其實這道題跟上道題是十分類似的,上道題目是删除相同的元素,這道題是删除等于給定值的元素,實際上這道題比上一道更加簡單了,如果上道題了解的同學可能已經對這道題有思路了。

實作思路

依然是雙指針,周遊數組。題目要求移除

等于

指定值的元素,那我們就在周遊的時候如果碰到

不等于

指定值的元素,就用慢指針更改它位置上元素不久OK了。

代碼(Java):

class Solution {
    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;
    }
}
           

代碼(Python):

class Solution(object):
    def removeElement(self, nums, val):
        i = 0
        for j in range(len(nums)):
            if nums[j] != val:
                nums[i] = nums[j]
                i += 1
        return i;
           

這次Python和Java實作方式相同了,大家可以對比看一下。

28-實作strStr()

題目要求:

給定一個 haystack 字元串和一個 needle 字元串,在 haystack 字元串中找出 needle 字元串出現的第一個位置 (從0開始)。如果不存在,則傳回 -1。

示例1:

輸入: haystack = "hello", needle = "ll"
輸出: 2
           

示例2:

輸入: haystack = "aaaaa", needle = "bba"
輸出: -1
           

題目很簡短,給定兩個字元串,如果第二個字元串在第一個字元串中出現,那麼傳回它

第一次出現的位置

,如果沒有出現,傳回

-1

就行。

簡單分析一下,什麼時候會不出現?

首先,一種情況是

haystack

needle

長,這樣子肯定不會存在。第二種情況就更好想了,就是單純第二個字元串沒有在第一個字元串中出現。

那如果出現了會有什麼特征?也就是說第二個字元串在第一個字元串中能找到相同的部分,題目要求傳回出現的第一個位置,那我們從前向後周遊第一個字元串就行了,如果某個元素和第二個字元串的首元素相同,那我們就挨着順序對比下去,如果不相同,接着上次周遊到的位置繼續周遊就行了,如果周遊到最後沒有發現相同的部分,就傳回-1。實際上,我們不需要周遊到第一個字元串的最後一個位置,為什麼?因為剩下的長度小于第二個字元串的時候肯定不會再出現了。

實作思路

首先确定兩個字元串的長度,用一根指針周遊

haystack

字元串,然後直接判斷

haystack

字元串從目前位置到

needle

長度的部分是否和

needle

是相同的,如果相同,直接傳回目前位置,如果不相同,繼續向後周遊。

代碼(Java):

class Solution {
  public int strStr(String haystack, String needle) {
        int haylen = haystack.length();
        int neelen = needle.length();
        for (int i = 0; i < haylen - neelen + 1; i++) {
            if (haystack.substring(i, i + neelen).equals(needle)) {
                return i;
                }
        }
    return -1;
    }
}
           

代碼(Python):

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        haylen = len(haystack)
        neelen = len(needle)
        for i in range(haylen-neelen +1):
            if haystack[i:i+neelen] == needle:
                return i
        return -1
           

好了,今天的題目分享就到這裡,這都是題庫裡面非常簡單的題目,注意消化分享,有不懂的地方多多留言交流哦~

你好,我是

goldsunC

讓我們一起進步吧!