數組和字符串(python),雙指針


數組簡介

數組是一種基本的數據結構,用於按順序存儲元素的集合。但是元素可以隨機存取,因為數組中的每個元素都可以通過數組索引來識別。

數組可以有一個或多個維度。這里我們從一維數組開始,它也被稱為線性數組。這里有一個例子:

在上面的例子中,數組 A 中有 6 個元素。也就是說,A 的長度是 6 。我們可以使用 A[0] 來表示數組中的第一個元素。因此,A[0] = 6 。類似地,A[1] = 3,A[2] = 8,依此類推。

 
尋找數組的中心索引
給定一個整數類型的數組 nums,請編寫一個能夠返回數組“中心索引”的方法。

我們是這樣定義數組中心索引的:數組中心索引的左側所有元素相加的和等於右側所有元素相加的和。

如果數組不存在中心索引,那么我們應該返回 -1。如果數組有多個中心索引,那么我們應該返回最靠近左邊的那一個。

示例 1:

輸入: 
nums = [1, 7, 3, 6, 5, 6]
輸出: 3
解釋: 
索引3 (nums[3] = 6) 的左側數之和(1 + 7 + 3 = 11),與右側數之和(5 + 6 = 11)相等。
同時, 3 也是第一個符合要求的中心索引。
示例 2:

輸入: 
nums = [1, 2, 3]
輸出: -1
解釋: 
數組中不存在滿足此條件的中心索引。
說明:

nums 的長度范圍為 [0, 10000]。
任何一個 nums[i] 將會是一個范圍在 [-1000, 1000]的整數。
class Solution(object):
    def pivotIndex(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
#       思路:通過求取整個數組的和記為sum_nums,依次遍歷每個元素,記為sum_left,sum_right,center,其中sum_left可通過每一次遍歷得出,sum_right=sum_nums-center-sum_left
        nums_len=len(nums)
        sum_nums=sum(nums)
        sum_left=0
        for i in range(nums_len):
            if i>=1:
                sum_left+=nums[i-1]
            sum_right=sum_nums-nums[i]-sum_left
            if sum_left==sum_right:
                return i
        return -1
至少是其他數字兩倍的最大數
在一個給定的數組nums中,總是存在一個最大元素 。

查找數組中的最大元素是否至少是數組中每個其他數字的兩倍。

如果是,則返回最大元素的索引,否則返回-1。

示例 1:

輸入: nums = [3, 6, 1, 0]
輸出: 1
解釋: 6是最大的整數, 對於數組中的其他整數,
6大於數組中其他元素的兩倍。6的索引是1, 所以我們返回1.
 

示例 2:

輸入: nums = [1, 2, 3, 4]
輸出: -1
解釋: 4沒有超過3的兩倍大, 所以我們返回 -1.
 

提示:

nums 的長度范圍在[1, 50].
每個 nums[i] 的整數范圍在 [0, 99].

 

class Solution(object):
    def dominantIndex(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
#思路:對原數組取出第一個最大值,去除該最大值的數組找出第二最大*2,比較
        import copy
        if len(nums)<=1:
            return 0
        max_number=max(nums)
        nums_=copy.copy(nums)
        nums_.remove(max_number)
        max_two_number=max(nums_)*2
        if max_number>=max_two_number:
            return nums.index(max_number)
        return -1
加一
給定一個由整數組成的非空數組所表示的非負整數,在該數的基礎上加一。

最高位數字存放在數組的首位, 數組中每個元素只存儲一個數字。

你可以假設除了整數 0 之外,這個整數不會以零開頭。

示例 1:

輸入: [1,2,3]
輸出: [1,2,4]
解釋: 輸入數組表示數字 123。
示例 2:

輸入: [4,3,2,1]
輸出: [4,3,2,2]
解釋: 輸入數組表示數字 4321。
class Solution:
    def plusOne(self, digits):
        """
        :type digits: List[int]
        :rtype: List[int]
        """
        
#     思路:通過字符串進行連接,轉int+1,在轉字符串,通過循環
        num=[str(i) for i in digits]
        num=int(''.join(num))+1
        num=str(num)
        res=[]
        for i in range(len(num)):
            res.append(int(num[i]))
        return res
楊輝三角
給定一個非負整數 numRows,生成楊輝三角的前 numRows 行

在楊輝三角中,每個數是它左上方和右上方的數的和。

示例:

輸入: 5
輸出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

 

class Solution(object):
    def generate(self, numRows):
        """
        :type numRows: int
        :rtype: List[List[int]]
        """
        
        #思路:除了第一行后其余每行都有兩個1,因而將第一行單獨列出來,第二行開始每行第一步添加1,然后開始計算上一行每兩個數的求和,最后在進行添加1,
        res=[]
        if numRows==0:
            return []
        res.append([1])
        for  i in range(1,numRows):
            res.append([1])
            for j in range(1,len(res[i-1])):
                res[i].append(res[i-1][j]+res[i-1][j-1])
            res[i].append(1)
        return res

 

Python的每個對象都分為可變和不可變,主要的核心類型中,數字、字符串、元組是不可變的,列表、字典是可變的。

對不可變類型的變量重新賦值,實際上是重新創建一個不可變類型的對象,並將原來的變量重新指向新創建的對象
(如果沒有其他變量引用原有對象的話(即引用計數為0),原有對象就會被回收)。 可變對象:如果進行的是淺復制,那么存在任何一個對象修改,其他對象也會一起修改(地址相同) 不可變對象,如果進行的是淺
復制,相當於深復制,地址不同
print '可變'
t=[1,3,4,1]
t_copy=t
t_copy.append(12)
print t,t_copy,id(t),id(t_copy)
m={'123':2,'sada':3}
m_copy=m
m['qq']=5
print m,m_copy,id(m),id(m_copy)
print '不可變'
k='232'
k_copy=k
k+='s'
print k,k_copy,id(k),id(k_copy)
d=10
d_copy=d
d_copy+=1
print d,d_copy,id(d),id(d_copy)


輸出結果:

可變
[1, 3, 4, 1, 12] [1, 3, 4, 1, 12] 140630062594024 140630062594024
{'qq': 5, 'sada': 3, '123': 2} {'qq': 5, 'sada': 3, '123': 2} 140630062705752 140630062705752
不可變
232s 232 140630062701904 140630062750056
10 11 94639729410192 94639729410168

 

 

list內置函數:
  len(list): 列表元素個數

  max(list): 列表元素最大值,但list不為空.為空報錯

  min
(list): 列表元素最小值,但list不為空.為空報錯
方法:

  添加:
    list.append(obj) : 在列表末尾添加新的對象

    list_extend(seq): 在列表末尾一次性追加另一個序列中的多個值(用新列表擴展原來的列表) (原地) (對於單個字符串,進行添加每個字符)

    list.insert(index,obj):  將對象插入列表(原地),index超過實際長度,則添加末尾
  刪除:
    
    list.remove(obj) :移除當前list,指定的元素,刪除成功返回 None, 否則報錯,(原地操作)(刪除為第一個出現)

    list.pop(): 根據index進行刪除元素, 返回刪除的元素,否則報錯.(原地)
  
    del list[index]: 刪除元素,原地
  查找:
    list.index(obj) :指定元素進行查找,返回其index,但不存在則報錯(返回第一個出現的index)
    
    list[index]: 指定索引進行查找,不存在報錯

  改:
    直接對指定位置進行賦值即可

  排序:
    list.sort(cmp=None,key=None,reverse=False)

        cmp -- 可選參數, 如果指定了該參數會使用該參數的方法進行排序。

        key -- 主要是用來進行比較的元素,只有一個參數,具體的函數的參數就是取自於可迭代對象中,指定可迭代對象中的一個元素來進行排序。(主要用於元祖等,在list中存儲的對象)

        reverse -- 排序規則,reverse = True 降序, reverse = False 升序(默認)。

  list.count(obj): 統計某個元素在列表中出現的次數
  list.reverse(): 對當前list進行翻轉(原地)
字符串
  是一個不可變對象,內置函數和方法 http://www.runoob.com/python/python-strings.html
 最長公共前綴
編寫一個函數來查找字符串數組中的最長公共前綴。

如果不存在公共前綴,返回空字符串 ""。

示例 1:

輸入: ["flower","flow","flight"]
輸出: "fl"
示例 2:

輸入: ["dog","racecar","car"]
輸出: ""
解釋: 輸入不存在公共前綴。
說明:

所有輸入只包含小寫字母 a-z 。
class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        
        
        """
#         思路,每一次獲取第一個元素的前幾個字符,與其他元素的前幾個字符進行比較,不相等,則返回上個長度的字符,
        if strs==[]:
            return ''
        if len(strs)==1:
            return strs[0]
        for i in range(1,len(strs[0])+1):
            current_str=strs[0][:i]
            for j  in range(1,len(strs)):
                next_str=strs[j][:i]
                if next_str!=current_str:
                    return strs[0][:i-1]
                
        return strs[0]
給定一個 haystack 字符串和一個 needle 字符串,在 haystack 字符串中找出 needle 字符串出現的第一個位置 (從0開始)。如果不存在,則返回  -1。

示例 1:

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

輸入: haystack = "aaaaa", needle = "bba"
輸出: -1
class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
#    思路:利用字符串中的index方法,進行尋找,不存在則通過try-except返回-1
        if len(needle)==0:
            return 0
        try:
            index_=haystack.index(needle)
        except:
            return -1
        return index_
二進制求和
給定兩個二進制字符串,返回他們的和(用二進制表示)。

輸入為非空字符串且只包含數字 1 和 0。

示例 1:

輸入: a = "11", b = "1"
輸出: "100"
示例 2:

輸入: a = "1010", b = "1011"
輸出: "10101"
class Solution(object):
    def addBinary(self, a, b):
        """
        :type a: str
        :type b: str
        :rtype: str
        """
#         int的操作: int(t,base)  base :2為二進制, 默認為十進制   bin()  進行二進制計算 ,返回一二二進制,形如:'ob1010'
        return bin(int(a,2)+int(b,2))[2:]
雙指針技巧,它可以幫助我們解決許多與數組/字符串相關的問題https://leetcode-cn.com/explore/learn/card/array-and-string/201/two-pointer-technique/786/

總結


總之,使用雙指針技巧的典型場景之一是你想要

從兩端向中間迭代數組。

這時你可以使用雙指針技巧:

一個指針從始端開始,而另一個指針從末端開始。

值得注意的是,這種技巧經常在排序數組中使用。

情景二:

這是你需要使用雙指針技巧的一種非常常見的情況:

同時有一個慢指針和一個快指針。

解決這類問題的關鍵是

確定兩個指針的移動策略。

與前一個場景類似,你有時可能需要在使用雙指針技巧之前對數組進行排序,也可能需要運用貪心想法來決定你的運動策略。

反轉字符串
編寫一個函數,其作用是將輸入的字符串反轉過來。

示例 1:

輸入: "hello"
輸出: "olleh"
示例 2:

輸入: "A man, a plan, a canal: Panama"
輸出: "amanaP :lanac a ,nalp a ,nam A"
class Solution(object):
    def reverseString(self, s):
        """
        :type s: str
        :rtype: str
        """
        # return s[::-1]
        # return (''.join(list(reversed(s))))
        
        #思路:利用雙指針方法,定義左指針和右指針,依次交換元素,字符串是不可變,因為可以將其通過list轉換為可變對象,然后在通過join進行連接,即可完成字符串的修改
        left=0
        s_list=list(s)
        right=len(s_list)-1
        while left<=right:
            temp=s[left]
            s_list[left]=s_list[right]
            s_list[right]=temp
            left+=1
            right-=1
        return ''.join(s_list)
兩數之和 II - 輸入有序數組
給定一個已按照升序排列 的有序數組,找到兩個數使得它們相加之和等於目標數。

函數應該返回這兩個下標值 index1 和 index2,其中 index1 必須小於 index2。

說明:

返回的下標值(index1 和 index2)不是從零開始的。
你可以假設每個輸入只對應唯一的答案,而且你不可以重復使用相同的元素。
示例:

輸入: numbers = [2, 7, 11, 15], target = 9
輸出: [1,2]
解釋: 27 之和等於目標數 9 。因此 index1 = 1, index2 = 2
class Solution(object):
    def twoSum(self, numbers, target):
        """
        :type numbers: List[int]
        :type target: int
        :rtype: List[int]
        """
        n=len(numbers)
        if n<2:
            return []
        left=0
        right=n-1
        while left<=right:
            if numbers[left]+numbers[right]==target:
#            答案是唯一的
                return [left+1,right+1]
            elif numbers[left]+numbers[right]<target:
                left+=1
            else:
                right-=1
        return []
情景2
移除元素
給定一個數組 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。

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

你不需要考慮數組中超出新長度后面的元素。
class Solution:
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        #定義雙指針,使用了兩個指針,i一個用於原始數組的迭代,k另一個總是指向新數組的最后一個位置
        k=0
        for i in range(len(nums)):
            if nums[i]!=val:
                nums[k]=nums[i]
                k+=1
        return k
        
最大連續1的個數
給定一個二進制數組, 計算其中最大連續1的個數。

示例 1:

輸入: [1,1,0,1,1,1]
輸出: 3
解釋: 開頭的兩位和最后的三位都是連續1,所以最大連續1的個數是 3.
注意:

輸入的數組只包含 0 和1。
輸入數組的長度是正整數,且不超過 10,000
class Solution(object):
    def findMaxConsecutiveOnes(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        #定義雙指針,一個記錄其連續的次數,一個用於迭代
        k=0
        return_=0
        for i in range(len(nums)):
            if nums[i]==1:
                k+=1
            else:
                return_=max(k,return_)
                k=0
        return max(return_,k)

 

翻轉字符串里的單詞
給定一個字符串,逐個翻轉字符串中的每個單詞。

示例:  

輸入: "the sky is blue",
輸出: "blue is sky the".
說明:

無空格字符構成一個單詞。
輸入字符串可以在前面或者后面包含多余的空格,但是反轉后的字符不能包括。
如果兩個單詞間有多余的空格,將反轉后單詞間的空格減少到只含一個。
class Solution(object):
    def reverseWords(self, s):
        """
        :type s: str
        :rtype: str
        """
        #思路:使用雙指針,第一個指針記錄不為' '的字符個數,第二個指針迭代
        import re
        list_s = re.split(' ', s)
        prev=0
        for i in range(len(list_s)):
            if list_s[i] != '':
                list_s[prev]=list_s[i]
                prev+=1
        del list_s[prev:]
        list_s.reverse()
        return ' '.join(list_s)
反轉字符串中的單詞 III
給定一個字符串,你需要反轉字符串中每個單詞的字符順序,同時仍保留空格和單詞的初始順序。

示例 1:

輸入: "Let's take LeetCode contest"
輸出: "s'teL ekat edoCteeL tsetnoc" 
注意:在字符串中,每個單詞由單個空格分隔,並且字符串中不會有任何額外的空格。
class Solution(object):
    def reverseWords(self, s):
        """
        :type s: str
        :rtype: str
        """
       #
        list_s=s.split(' ')
        for i in range(len(list_s)):
           #下面兩種形式都可以實現字符的翻轉,但是不可用指針形式對字符進行賦值翻轉,因為字符是不可變
            # list_s[i]=''.join(reversed(list_s[i]))
            list_s[i]=list_s[i][::-1]
        return ' '.join(list_s)
刪除排序數組中的重復項
給定一個排序數組,你需要在原地刪除重復出現的元素,使得每個元素只出現一次,返回移除后數組的新長度。

不要使用額外的數組空間,你必須在原地修改輸入數組並在使用 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。

你不需要考慮數組中超出新長度后面的元素。
class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
#         思路:使用雙指針,一個記錄不重復的元素,一個迭代
        pre=0
        for i in range(1,len(nums)):
            if nums[i]!=nums[pre]:
                nums[pre+1]=nums[i]
                pre+=1
        del nums[pre+1:]
                
移動零
給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。

示例:

輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]
說明:

必須在原數組上操作,不能拷貝額外的數組。
盡量減少操作次數。
class Solution(object):
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
#    思路: 利用雙指針,一個記錄不為0的個數,一個迭代
        pre=0
        for i in range(len(nums)):
            if nums[i]!=0:
                nums[pre]=nums[i]
                pre+=1
        for k in range(pre,len(nums)):
            nums[k]=0

 數組練習題:

 

643. 子數組最大平均數 I
給定 n 個整數,找出平均數最大且長度為 k 的連續子數組,並輸出該最大平均數。
示例 1:
輸入: [1,12,-5,-6,50,3], k = 4
輸出: 12.75
解釋: 最大平均數 (12-5-6+50)/4 = 51/4 = 12.75
注意:
1 <= k <= n <= 30,000。
所給數據范圍 [-10,000,10,000]。
https://leetcode-cn.com/problems/maximum-average-subarray-i/
class Solution(object):
    def findMaxAverage(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: float
        """
#     思路:利用雙指針,一前一后,前后差距為k
        res_sum=sum_=sum(nums[:k])
        left=0
        right=k
        while right<len(nums):
            sum_-=nums[left]
            sum_+=nums[right]
            res_sum=max(sum_,res_sum)
            left+=1
            right+=1
        return res_sum*1.0/k
    
914:卡牌分組

給定一副牌,每張牌上都寫着一個整數。
此時,你需要選定一個數字 X,使我們可以將整副牌按下述規則分成 1 組或更多組:
每組都有 X 張牌。
組內所有的牌上都寫着相同的整數。
僅當你可選的 X >= 2 時返回 true。
示例 1:

輸入:[1,2,3,4,4,3,2,1]
輸出:true
解釋:可行的分組是 [1,1],[2,2],[3,3],[4,4]
示例 2:

輸入:[1,1,1,2,2,2,3,3]
輸出:false
解釋:沒有滿足要求的分組。
示例 3:

輸入:[1]
輸出:false
解釋:沒有滿足要求的分組。
示例 4:

輸入:[1,1]
輸出:true
解釋:可行的分組是 [1,1]
示例 5:

輸入:[1,1,2,2,2,2]
輸出:true
解釋:可行的分組是 [1,1],[2,2],[2,2]

提示:

1 <= deck.length <= 10000
0 <= deck[i] < 10000
https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/
class Solution(object):
    def hasGroupsSizeX(self, deck):
        """
        :type deck: List[int]
        :rtype: bool
        """
#         思路:有題目可知,可通過dict求取每個元素 個數,並判斷他們之間是否存在公約數(不為1),存在返回True,
        if deck==[]:
            return []
        dict_={}
        for i in deck:
            if i not in dict_:
                dict_[i]=0
            dict_[i]+=1
        print dict_
        num_min=min(dict_.values())
        if num_min==1:
            return False
        for i in range(2,num_min+1):
            flag=True
            #對每個數字的次數進行對i求余,如果全部都為0,那么表明該全部元素之間存在公約數
            for j in dict_:
                if dict_[j]%i!=0:
                    flag=False
            if flag==True:
                return True
        return False

        

 

941:有效的山脈數組
給定一個整數數組 A,如果它是有效的山脈數組就返回 true,否則返回 false。

讓我們回顧一下,如果 A 滿足下述條件,那么它是一個山脈數組:

A.length >= 3
在 0 < i < A.length - 1 條件下,存在 i 使得:
A[0] < A[1] < ... A[i-1] < A[i]
A[i] > A[i+1] > ... > A[B.length - 1]
 

示例 1:

輸入:[2,1]
輸出:false
示例 2:

輸入:[3,5,5]
輸出:false
示例 3:

輸入:[0,3,2,1]
輸出:true
 

提示:

0 <= A.length <= 10000
0 <= A[i] <= 10000 
https://leetcode-cn.com/problems/valid-mountain-array/
class Solution(object):
    def validMountainArray(self, A):
        """
        :type A: List[int]
        :rtype: bool
        """
        #思路: 定義雙指針,,雙向遍歷,前后元素滿足條件則進行left  or  right 進行操作,
        if len(A)<=2:
            return False
        left=0
        right=len(A)-1
        for i in range(len(A)-1):
            if A[left+1]>A[left] :
                left+=1
            if A[right]<A[right-1]:
                right-=1
        if left!=right or right==len(A)-1 or left==0:
            return False
        return True
905:按奇偶排序數組
給定一個非負整數數組 A,返回一個由 A 的所有偶數元素組成的數組,后面跟 A 的所有奇數元素。

你可以返回滿足此條件的任何數組作為答案。

 

示例:

輸入:[3,1,2,4]
輸出:[2,4,3,1]
輸出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也會被接受。
 

提示:

1 <= A.length <= 5000
0 <= A[i] <= 5000
https://leetcode-cn.com/problems/sort-array-by-parity/
class Solution(object):
    def sortArrayByParity(self, A):
        """
        :type A: List[int]
        :rtype: List[int]
        """
        odd=[]
        even=[]
        for i in A:
            if i%2:
                odd.append(i)
            else:
                even.append(i)
        even.extend(odd)
        return even
922: 按奇偶排序數據2
給定一個非負整數數組 A, A 中一半整數是奇數,一半整數是偶數。

對數組進行排序,以便當 A[i] 為奇數時,i 也是奇數;當 A[i] 為偶數時, i 也是偶數。

你可以返回任何滿足上述條件的數組作為答案。

 

示例:

輸入:[4,2,5,7]
輸出:[4,5,2,7]
解釋:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也會被接受。
 

提示:

2 <= A.length <= 20000
A.length % 2 == 0
0 <= A[i] <= 1000
 
class Solution(object):
    def sortArrayByParityII(self, A):
        """
        :type A: List[int]
        :rtype: List[int]
        """
        odd=[]
        even=[]
        res=[]
        for i in A:
            if i%2:
                odd.append(i)
            else:
                even.append(i)
        for i in range(len(A)/2):
            res.append(even[i])
            res.append(odd[i])
        return res
830. 較大分組的位置
在一個由小寫字母構成的字符串 S 中,包含由一些連續的相同字符所構成的分組。

例如,在字符串 S = "abbxxxxzyy" 中,就含有 "a", "bb", "xxxx", "z""yy" 這樣的一些分組。

我們稱所有包含大於或等於三個連續字符的分組為較大分組。找到每一個較大分組的起始和終止位置。

最終結果按照字典順序輸出。

示例 1:

輸入: "abbxxxxzzy"
輸出: [[3,6]]
解釋: "xxxx" 是一個起始於 3 且終止於 6 的較大分組。
示例 2:

輸入: "abc"
輸出: []
解釋: "a","b""c" 均不是符合要求的較大分組。
示例 3:

輸入: "abcdddeeeeaabbbcd"
輸出: [[3,5],[6,9],[12,14]]
說明:  1 <= S.length <= 1000
https://leetcode-cn.com/problems/positions-of-large-groups/
class Solution(object):
    def largeGroupPositions(self, S):
        """
        :type S: str
        :rtype: List[List[int]]
        """
        if len(S)<=2:
            return []
        left=0
        right=1
        count=1
        res=[]
        #思路: 利用雙指針,進行遍歷,滿足則count+1,不滿足count-1,如果最后還滿足,那么記性判斷count是否大於等於3
        while right<len(S):
            if S[right]==S[left] and right!=len(S)-1:
                count+=1
                right+=1
            elif S[right]!=S[left]:
                if count>=3:
                    res.append([left,right-1])
                left=right
                right+=1
                count=1
            elif S[right]==S[left] and right==len(S)-1:
                count+=1
                if count>=3:
                    res.append([left,right])
                break
        return res
            

 

665. 非遞減數列
給定一個長度為 n 的整數數組,你的任務是判斷在最多改變 1 個元素的情況下,該數組能否變成一個非遞減數列。

我們是這樣定義一個非遞減數列的: 對於數組中所有的 i (1 <= i < n),滿足 array[i] <= array[i + 1]。

示例 1:

輸入: [4,2,3]
輸出: True
解釋: 你可以通過把第一個4變成1來使得它成為一個非遞減數列。
示例 2:

輸入: [4,2,1]
輸出: False
解釋: 你不能在只改變一個元素的情況下將其變為非遞減數列。
說明:  n 的范圍為 [1, 10,000]。
https://leetcode-cn.com/problems/non-decreasing-array/
class Solution(object):
    def checkPossibility(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
#    思路:通過簡單的例子分析,會發現當第i個數字小於第i-1數字時,有兩種替換方式,第一種是令第i個數字等於第i-1數字,另一種是第i-1數字等於第i數字.兩種方式 的判別條件為i-2數字與第i個數字的比較,(也可以使用i-1與i+1進行比較,不過要注意范圍)[1,3,1,2],[2,3,1,4]
        flag=0
        for i in range(1,len(nums)):
            if nums[i]<nums[i-1]:
                flag+=1
                if flag>1:
                    return False
                if i-2 < 0 or nums[i-2] <= nums[i]:
                    nums[i-1] = nums[i]
                else:
                    nums[i] = nums[i-1]
        return True
628. 三個數的最大乘積
給定一個整型數組,在數組中找出由三個數組成的最大乘積,並輸出這個乘積。

示例 1:

輸入: [1,2,3]
輸出: 6
示例 2:

輸入: [1,2,3,4]
輸出: 24
注意:

給定的整型數組長度范圍是[3,104],數組中所有的元素范圍是[-1000, 1000]。
輸入的數組中任意三個數的乘積不會超出32位有符號整數的范圍。
https://leetcode-cn.com/problems/maximum-product-of-three-numbers/
class Solution(object):
    def maximumProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
#        思路:三個數的乘積最大,兩種情況,第一種最大的三個數(大於0),第二種,最小的兩個數(小於0)與最大的數
        if len(nums)<3:
            return 0
        nums.sort()
        return max(nums[0]*nums[1]*nums[-1],nums[-1]*nums[-2]*nums[-3])
896. 單調數列
如果數組是單調遞增或單調遞減的,那么它是單調的。

如果對於所有 i <= j,A[i] <= A[j],那么數組 A 是單調遞增的。 如果對於所有 i <= j,A[i]> = A[j],那么數組 A 是單調遞減的。

當給定的數組 A 是單調數組時返回 true,否則返回 false。

 

示例 1:

輸入:[1,2,2,3]
輸出:true
示例 2:

輸入:[6,5,4,4]
輸出:true
示例 3:

輸入:[1,3,2]
輸出:false
示例 4:

輸入:[1,2,4,5]
輸出:true
示例 5:

輸入:[1,1,1]
輸出:true
https://leetcode-cn.com/problems/monotonic-array/
class Solution(object):
    def isMonotonic(self, A):
        """
        :type A: List[int]
        :rtype: bool
        """
        # 思路 :  對原數組進行復制,通過對原數組進行正向排序,相等返回True,不相等,有可能該原數組為逆序
        if len(A)<=2:
            return True
        import copy
        A_copy=copy.copy(A)
        A.sort()
        if A_copy==A:
            return True
        if A_copy[::-1]==A:
            return True
        return False

 

532. 數組中的K-diff數對
給定一個整數數組和一個整數 k, 你需要在數組里找到不同的 k-diff 數對。這里將 k-diff 數對定義為一個整數對 (i, j), 其中 i 和 j 都是數組中的數字,且兩數之差的絕對值是 k.

示例 1:

輸入: [3, 1, 4, 1, 5], k = 2
輸出: 2
解釋: 數組中有兩個 2-diff 數對, (1, 3) 和 (3, 5)。
盡管數組中有兩個1,但我們只應返回不同的數對的數量。
示例 2:

輸入:[1, 2, 3, 4, 5], k = 1
輸出: 4
解釋: 數組中有四個 1-diff 數對, (1, 2), (2, 3), (3, 4) 和 (4, 5)。
示例 3:

輸入: [1, 3, 1, 5, 4], k = 0
輸出: 1
解釋: 數組中只有一個 0-diff 數對,(1, 1)。
注意:

數對 (i, j) 和數對 (j, i) 被算作同一數對。
數組的長度不超過10,000。
所有輸入的整數的范圍在 [-1e7, 1e7]。
’‘’
思路:
        對原數組進行排序,然后通過雙指針進行遍歷,如果前后原數組在前后指針的數值相減的絕對值等於K,那么count+1,前后指針分別加1,如果大於k(表明前后指針的數組值相差過大,那么對后指針+1),否則快指針進行+1,
        過程中:主要注意兩個地方,1.數組對有可能存在重復,所以要對每一步生成的數組對進行記錄,對重復的進行舍去。
    2.后指針不能超過前指針 ,如果相等,那么對后指針進行+1處理。

‘’‘
class Solution(object):
    def findPairs(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        nums.sort()
        slow_index=0
        fast_index=1
        count_=0
        set_=set()
        while fast_index<len(nums):
            if abs(nums[slow_index]-nums[fast_index])==k and nums[fast_index]+nums[slow_index] not in set_:
                set_.add(nums[fast_index]+nums[slow_index]) 
                slow_index+=1
                fast_index+=1

                count_+=1
            elif abs(nums[slow_index]-nums[fast_index])>k:
                slow_index+=1
            else:
                fast_index+=1
            if slow_index==fast_index:
                fast_index+=1
        return count_
        
925. 長按鍵入

你的朋友正在使用鍵盤輸入他的名字 name。偶爾,在鍵入字符 c 時,按鍵可能會被長按,而字符可能被輸入 1 次或多次。

你將會檢查鍵盤輸入的字符 typed。如果它對應的可能是你的朋友的名字(其中一些字符可能被長按),那么就返回 True。

 

示例 1:

輸入:name = "alex", typed = "aaleex"
輸出:true
解釋:'alex' 中的 'a''e' 被長按。
示例 2:

輸入:name = "saeed", typed = "ssaaedd"
輸出:false
解釋:'e' 一定需要被鍵入兩次,但在 typed 的輸出中不是這樣。
示例 3:

輸入:name = "leelee", typed = "lleeelee"
輸出:true
示例 4:

輸入:name = "laiden", typed = "laiden"
輸出:true
解釋:長按名字中的字符並不是必要的。
 

提示:

name.length <= 1000
typed.length <= 1000
name 和 typed 的字符都是小寫字母。
'''
思路:利用雙指針分別遍歷兩個數組,對name的數組依次取出一個數,對typed數組進行遍歷,如果遇到與name取出的元素相等,則推出,否則type_index+1
  注意點:1.當name遍歷到最后一個元素時,type是否還有元素進行遍歷。
  2. 避免name遍歷時,type已經沒有元素可以進行遍歷
'''

class Solution(object):
    def isLongPressedName(self, name, typed):
        """
        :type name: str
        :type typed: str
        :rtype: bool
        """
        name_index=0       #name的index
        typed_index=0
        while name_index<len(name):
            char=name[name_index]
            name_index+=1
            if name_index==len(name) and typed_index==len(typed):   #1.避免name遍歷最后一個元素時,type是否還有元素進行遍歷。
                return False
            #2.避免遍歷時,type已經沒有元素可以進行遍歷
            flat=False
            while typed_index<len(typed):
                if char==typed[typed_index]:
                    typed_index+=1
                    flat=True
                    break
                typed_index+=1
            if not flat:
                return False
        return True
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM