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
讓我們一起進步吧!