leetcode數組中的問題(七)

目錄

243. 最短單詞距離🔒

766. 託普利茨矩陣

面試題 17.04. 消失的數字

169. 多數元素

1287. 有序數組中出現次數超過25%的元素

119. 楊輝三角 II

面試題 16.17. 連續數列

1170. 比較字符串最小字母出現頻次

1089. 複寫零

448. 找到所有數組中消失的數字

442. 數組中重複的數據


 

243. 最短單詞距離

https://leetcode-cn.com/problems/shortest-word-distance/

給定一個單詞列表和兩個單詞 word1 和 word2,返回列表中這兩個單詞之間的最短距離。

示例:假設 words = ["practice", "makes", "perfect", "coding", "makes"],輸入: word1 = “coding”, word2 = “practice”,輸出: 3輸入: word1 = "makes", word2 = "coding",輸出: 1
注意:你可以假設 word1 不等於 word2, 並且 word1 和 word2 都在列表裏。

思路

一:兩重循環,查找是否有符合條件的,並更新最短距離,時間複雜度O(kn^2),n是words數組的長度,k是words中單詞的最大長度。

二:優化的二重循環,時間複雜度O(nk+n^2),rec_1和rec_2分別記錄了word1和word2在words中的下標,然後在倆數組中找到最小的差值即ok了。

class Solution(object):
    def shortestDistance(self, words, word1, word2):
        """
        :type words: List[str]
        :type word1: str
        :type word2: str
        :rtype: int
        """
        rec_1, rec_2 = [], []

        for i in range(len(words)):
            if words[i] == word1:
                rec_1.append(i)
            elif words[i] == word2:
                rec_2.append(i)
        res = abs(rec_1[0] - rec_2[0])
        for i in rec_1:
            for j in rec_2:
                res = min(res, abs(i-j))
        return res

三:用idx1和idx2分別記錄word1和word2的最新出現的位置,每次發現一個新的單詞,不必要再循環遍歷,因爲已經記錄過最新的位置,時間複雜度O(kn)。

class Solution(object):
    def shortestDistance(self, words, word1, word2):
        res, idx1, idx2 = len(words), -1, -1

        for i in range(len(words)):
            if words[i] == word1:
                idx1 = i
            elif words[i] == word2:
                idx2 = i
            if idx1 != -1 and idx2!= -1:
                res = min(res, abs(idx1 - idx2))
        return res

766. 託普利茨矩陣

https://leetcode-cn.com/problems/toeplitz-matrix/

如果一個矩陣的每一方向由左上到右下的對角線上具有相同元素,那麼這個矩陣是託普利茨矩陣。

給定一個 M x N 的矩陣,當且僅當它是託普利茨矩陣時返回 True。

示例 1:輸入: matrix = [[1,2,3,4],[5,1,2,3],[9,5,1,2]],輸出: True,解釋:在上述矩陣中, 其對角線爲:"[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]"。各條對角線上的所有元素均相同, 因此答案是True。
示例 2:輸入:matrix = [[1,2],[2,2]],輸出: False,解釋: 對角線"[1, 2]"上的元素不同。
說明: matrix 是一個包含整數的二維數組。matrix 的行數和列數均在 [1, 20]範圍內。matrix[i][j] 包含的整數在 [0, 99]範圍內。

思路

一:對角線

class Solution(object):
    def isToeplitzMatrix(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: bool
        """
        if not matrix or not matrix[0]:
            return False
        m, n = len(matrix), len(matrix[0])
        rec = [0] * (m + n - 1)
        idx = 0
        for i in range(m -1 , 0, -1):
            rec[idx] = matrix[i][0]
            idx += 1
        for j in range(0, n):
            rec[idx] = matrix[0][j]
            idx += 1 

        for i in range(m):
            for j in range(n):
                if matrix[i][j] != rec[j - i + m - 1]:
                    return False
        return True

二:檢查左上鄰居。

面試題 17.04. 消失的數字

https://leetcode-cn.com/problems/missing-number-lcci/

數組nums包含從0到n的所有整數,但其中缺了一個。請編寫代碼找出那個缺失的整數。你有辦法在O(n)時間內完成嗎?

注意:本題相對書上原題稍作改動

示例 1:輸入:[3,0,1],輸出:2
示例 2:輸入:[9,6,4,2,3,5,7,0,1],輸出:8

思路

一:創建一個n+1個元素的列表,若某值出現,則以該值爲下標的元素計1。

class Solution(object):
    def missingNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        rec = [0] * (len(nums)+1)

        for num in nums:
            rec[num] = 1

        for i in range(len(rec)):
            if rec[i] == 0:
                return i

二:copy一下leetcode上大神的解法,https://leetcode-cn.com/problems/missing-number-lcci/solution/onshi-jian-fu-za-du-o1kong-jian-fu-za-du-shi-xian-/,借用異或操作,res = res ^ x ^ x。對同一個值異或兩次,那麼結果等於它本身,所以我們對res從0-nums.length進行異或,同時對nums數組中的值進行異或,出現重複的會消失,所以最後res的值是隻出現一次的數字,也就是nums數組中缺失的那個數字。

class Solution(object):
    def missingNumber(self, nums):
        res = 0

        for i in range(len(nums)):
            res ^= i
            res ^= nums[i] 
        res ^= len(nums)
        return res   

169. 多數元素

https://leetcode-cn.com/problems/majority-element/

給定一個大小爲 n 的數組,找到其中的多數元素。多數元素是指在數組中出現次數大於 ⌊ n/2 ⌋ 的元素。你可以假設數組是非空的,並且給定的數組總是存在多數元素。

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

思路

一:排序,因爲此處衆數的定義是出現次數大於 ⌊ n/2 ⌋ 的元素,且保證存在,則該數一定是下標⌊ n/2 ⌋的元素,例如長度爲3,則下標1上的元素一定是結果;長度爲4,則下標2上的元素一定是結果。

class Solution(object):
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums = sorted(nums)
        return nums[len(nums)//2]

二:消消樂。開闢一個列表,列表的第一個元素放候選衆數,第二個元素放計數,若遍歷的元素與候選衆數同,則計數加1,若不同,計數減1;若計數爲0,則將該數作爲新的候選衆數,並計1;最終的結果第一個元素是衆數,第二個元素也必然大於0。其實方法一和方法二能用都是因爲題目中衆數的定義,長度必須佔到 ⌊ n/2 ⌋ +1。後面看了一下題解,其實與官方題解的法6一樣。https://leetcode-cn.com/problems/majority-element/solution/qiu-zhong-shu-by-leetcode-2/,感覺官方寫的挺清晰的,copy一下。如果我們把衆數記爲 +1+1 ,把其他數記爲 −1−1 ,將它們全部加起來,顯然和大於 0 ,從結果本身我們可以看出衆數比其他數多。本質上,就是找 nums 的一個後綴 suf ,其中 suf[0] 就是後綴中的衆數。我們維護一個計數器,如果遇到一個我們目前的候選衆數,就將計數器加一,否則減一。只要計數器等於 0 ,我們就將 nums 中之前訪問的數字全部 忘記 ,並把下一個數字當做候選的衆數。直觀上這個算法不是特別明顯爲何是對的,我們先看下面這個例子(豎線用來劃分每次計數器歸零的情況)[7, 7, 5, 7, 5, 1 | 5, 7 | 5, 5, 7, 7 | 7, 7, 7, 7]首先,下標爲 0 的 7 被當做衆數的第一個候選。在下標爲 5 處,計數器會變回0 。所以下標爲 6 的 5 是下一個衆數的候選者。由於這個例子中 7 是真正的衆數,所以通過忽略掉前面的數字,我們忽略掉了同樣多數目的衆數和非衆數。因此, 7 仍然是剩下數字中的衆數。[7, 7, 5, 7, 5, 1 | 5, 7 | 5, 5, 7, 7 | 5, 5, 5, 5]現在,衆數是 5 (在計數器歸零的時候我們把候選從 7 變成了 5)。此時,我們的候選者並不是真正的衆數,但是我們在 遺忘 前面的數字的時候,要去掉相同數目的衆數和非衆數(如果遺忘更多的非衆數,會導致計數器變成負數)。因此,上面的過程說明了我們可以放心地遺忘前面的數字,並繼續求解剩下數字中的衆數。最後,總有一個後綴滿足計數器是大於 0 的,此時這個後綴的衆數就是整個數組的衆數。

class Solution(object):
    def majorityElement(self, nums):
        rec = [nums[0], 1]

        for i in range(1,len(nums)):
            if rec[1] == 0:
                rec = [nums[i], 1]
            elif rec[0] == nums[i]:
                rec[1] += 1
            else:
                rec[1] -= 1
        return rec[0]

1287. 有序數組中出現次數超過25%的元素

https://leetcode-cn.com/problems/element-appearing-more-than-25-in-sorted-array/

給你一個非遞減的 有序 整數數組,已知這個數組中恰好有一個整數,它的出現次數超過數組元素總數的 25%。請你找到並返回這個整數。

示例:輸入:arr = [1,2,2,6,6,6,6,7,10],輸出:6
提示:1 <= arr.length <= 10^4,0 <= arr[i] <= 10^5

思路

一:原數組有序,則可以對數組進行一次遍歷,並統計每個數出現的次數。只要發現某個數出現的次數超過數組 arr 長度的四分之一,那麼這個數即爲答案。

class Solution:
    def findSpecialInteger(self, arr):
        n = len(arr)
        cur, cnt = arr[0], 0
        for i in range(n):
            if arr[i] == cur:
                cnt += 1
                if cnt * 4 > n:
                    return cur
            else:
                cur, cnt = arr[i], 1
        return -1

二:二分法,copy了leetcode的官方題解,https://leetcode-cn.com/problems/element-appearing-more-than-25-in-sorted-array/solution/you-xu-shu-zu-zhong-chu-xian-ci-shu-chao-guo-25d-3/

根據題目要求,滿足條件的整數 x 至少在數組 arr 中出現了 span = arr.length / 4 + 1 次,那麼我們可以斷定:數組 arr 中的元素 arr[0], arr[span], arr[span * 2], ... 一定包含 x。

我們可以使用反證法證明上述的結論。假設 arr[0], arr[span], arr[span * 2], ... 均不爲 x,由於數組 arr 已經有序,那麼 x 只會連續地出現在 arr[0], arr[span], arr[span * 2], ... 中某兩個相鄰元素的間隔中,因此其出現的次數最多爲 span - 1 次,這與它至少出現 span 次相矛盾。

有了上述的結論,我們就可以依次枚舉 arr[0], arr[span], arr[span * 2], ... 中的元素,並將每個元素在數組 arr 上進行二分查找,得到其在 arr 中出現的位置區間。如果該區間的長度至少爲 span,那麼我們就得到了答案。

class Solution(object):
    def findSpecialInteger(self, arr):
        # 因爲range中的步長取得n//4,該值不能爲0。
        if len(arr) <= 2:
            return arr[0]
        if len(arr) == 3:
            return arr[1]
        n = len(arr)

        for i in range(0, n, n // 4):
            cnt = self._higher(arr, arr[i]) - self._lower(arr, arr[i]) + 1
            if cnt > n // 4:
                return arr[i]

    def _lower(self, nums, target):
        # [l, r], 找到第一個等於該數的數
        l, r = 0, len(nums) - 1
        loc = -1
        while l <= r:
            mid = l + (r - l) // 2
            if nums[mid] < target:
                loc = mid
                l = mid + 1
            else:
                r = mid - 1
        return loc + 1

    def _higher(self, nums, target):
        # [l, r], 找到最後一個等於該數的數
        l, r = 0, len(nums) - 1
        loc = r + 1
        while l <= r:
            mid = l + (r - l) // 2
            if nums[mid] <= target:
                l = mid + 1
            else:
                loc = mid
                r = mid - 1
        return loc - 1

    # def _lower(self, nums, target):
    #     l, r = 0, len(nums) - 1
    #     while l < r:
    #         mid = l + (r - l) // 2
    #         if nums[mid] < target:
    #             l = mid + 1
    #         else:
    #             r = mid
    #     if nums[l] == target:
    #         return l
    #     return -1
    # 
    # def _higher(self, nums, target):
    #     l, r = 0, len(nums) - 1
    #     while l < r:
    #         mid = l + (r - l + 1) // 2
    #         if nums[mid] <= target:
    #             l = mid
    #         else:
    #             r = mid - 1
    #     if nums[r] != target:
    #         return -1
    #     return r
 

一個有趣的庫bisect,使用時保證原數組有序。

bisect_left:在有序數組中新的元素x應該插入的位置i,並保證a[:i]<x,a[i:]>=x,i是第一個大於等於x的元素的下標,該題中爲等於x的最小的下標(因爲必存在等於)。

bisect_right:在有序數組中新的元素x應該插入的位置i,並保證a[:i]<=x,a[i:]>x,i是第一個大於x元素的下標,在該題中i-1是等於x的最大的下標(因爲必存在等於)。

bisect_left(a, x[, lo[, hi]]) -> index
    Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e < x, and all e in a[i:] have e >= x.  So if x already appears in the list, i points just before the leftmost x already there.

bisect_right(a, x[, lo[, hi]]) -> index
    Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e <= x, and all e in a[i:] have e > x.  So if x already appears in the list, i points just beyond the rightmost x already there 

class Solution(object):
    def findSpecialInteger(self, arr):
        # 因爲range中的步長取得n//4,該值不能爲0。
        if len(arr) <= 2:
            return arr[0]
        if len(arr) == 3:
            return arr[1]
        n = len(arr)

        for i in range(0, n, n // 4):
            # 與之前自定義的元素不同,這邊不用加1,具體見上面文字
            cnt = bisect.bisect_right(arr, arr[i]) - bisect.bisect_left(arr, arr[i])
            if cnt > n // 4:
                return arr[i]

119. 楊輝三角 II

https://leetcode-cn.com/problems/pascals-triangle-ii/

給定一個非負索引 k,其中 k ≤ 33,返回楊輝三角的第 k 行。在楊輝三角中,每個數是它左上方和右上方的數的和。

示例:輸入: 3,輸出: [1,3,3,1]
進階:你可以優化你的算法到 O(k) 空間複雜度嗎?

思路

一:借用118. 楊輝三角的思路,把所有行都求出來,返回最後一行,O(n^2)的時間空間複雜度。

class Solution(object):
    def getRow(self, rowIndex):
        """
        :type rowIndex: int
        :rtype: List[int]
        """
        if rowIndex == 0:
            return [1]
        rec = [[1]]
        for i in range(1, rowIndex + 1):
            tmp = [1]
            for j in range(1, len(rec[-1])):
                tmp.append(rec[-1][j-1] + rec[-1][j])
            tmp += [1]
            rec.append(tmp)
        return rec[-1]

二:我們發現,正在考慮的這一行只與上一行有關係,故只需要保留上一行,既可以只用兩行,O(n^2)的時間複雜度,O(n)的空間複雜度。

class Solution(object):
    def getRow(self, rowIndex):
        if rowIndex == 0:
            return [1]
        rec = [[0] * (rowIndex+1) for _ in range(2)]
        for i in range(0, rowIndex + 1):
            rec[i%2][0] = 1
            for j in range(1, i):
                rec[i%2][j] = rec[(i+1)%2][j - 1] + rec[(i+1) % 2][j]
            rec[i%2][i] = 1
        return rec[rowIndex % 2]

三:組合數,copy一下leetcode大佬的題解,https://leetcode-cn.com/problems/pascals-triangle-ii/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by--28/

如果熟悉楊輝三角,應該記得楊輝三角其實可以看做由組合數構成。

組合數的相關公式,C_{n}^{k} = C_{n}^{k-1}\times (n - k + 1) / k

class Solution(object):
    def getRow(self, rowIndex):
        rec = [[1] * (rowIndex + 1) for _ in range(2)]
        for i in range(1, rowIndex + 1):
            for j in range(1, i):
                rec[i % 2][j] = rec[(i + 1) % 2][j - 1] + rec[(i + 1) % 2][j]       
        return rec[rowIndex % 2]

 

面試題 16.17. 連續數列

https://leetcode-cn.com/problems/contiguous-sequence-lcci/

給定一個整數數組(有正數有負數),找出總和最大的連續數列,並返回總和。

示例:輸入: [-2,1,-3,4,-1,2,1,-5,4],輸出: 6,解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。
進階:如果你已經實現複雜度爲 O(n) 的解法,嘗試使用更爲精妙的分治法求解。

思路

一:用res記錄截止目前的最大值,local_sum表示前面的累加和,若其小於0,則表示在其基礎累加會起副作用,故丟棄所有值,重新累加。

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        res = nums[0]
        local_sum = nums[0]

        for i in range(1, len(nums)):
            if local_sum < 0:
                local_sum = nums[i]
            else:
                local_sum += nums[i]
            res = max(res, local_sum)
        return res

1170. 比較字符串最小字母出現頻次

https://leetcode-cn.com/problems/compare-strings-by-frequency-of-the-smallest-character/

我們來定義一個函數 f(s),其中傳入參數 s 是一個非空字符串;該函數的功能是統計 s  中(按字典序比較)最小字母的出現頻次。例如,若 s = "dcce",那麼 f(s) = 2,因爲最小的字母是 "c",它出現了 2 次。現在,給你兩個字符串數組待查表 queries 和詞彙表 words,請你返回一個整數數組 answer 作爲答案,其中每個 answer[i] 是滿足 f(queries[i]) < f(W) 的詞的數目,W 是詞彙表 words 中的詞。

示例 1:輸入:queries = ["cbd"], words = ["zaaaz"],輸出:[1],解釋:查詢 f("cbd") = 1,而 f("zaaaz") = 3 所以 f("cbd") < f("zaaaz")。
示例 2:輸入:queries = ["bbb","cc"], words = ["a","aa","aaa","aaaa"],輸出:[1,2],解釋:第一個查詢 f("bbb") < f("aaaa"),第二個查詢 f("aaa") 和 f("aaaa") 都 > f("cc")。
提示:1 <= queries.length <= 2000,1 <= words.length <= 2000,1 <= queries[i].length, words[i].length <= 10,queries[i][j], words[i][j] 都是小寫英文字母

思路

一:利用好條件很重要,1 <= queries[i].length, words[i].length <= 10,即所謂的f函數即helper的返回值一定是小於等於10的,故而我們可用計數排序,用rec[i]記錄返回值是i的有幾個元素,由於 f("aaa") 和 f("aaaa") 都 > f("cc"),在奇數排序的基礎上,我們重新定義rec,rec[i]記錄返回值大於等於i的有幾個元素,即是原先的rec的rec[i:]的累加和。且要是嚴格的小於不能等於,故res[i] = rec[v + 1]。

class Solution(object):
    def numSmallerByFrequency(self, queries, words):
        """
        :type queries: List[str]
        :type words: List[str]
        :rtype: List[int]
        """
        rec = [0] * 12
        for i in range(len(words)):
            v = self._helper(words[i])
            rec[v] += 1

        for i in range(9, -1, -1):
            rec[i] += rec[i+1]
        res = [0] * len(queries)
        for i in range(len(queries)):
            v = self._helper(queries[i])
            res[i] = rec[v + 1]
        return res

    
    def _helper(self, s):
        rec = [0] * 26
        for c in s:
            rec[ord(c) - ord("a")] += 1

        for i in range(26):
            if rec[i] != 0:
                return rec[i]
        return -1

1089. 複寫零

https://leetcode-cn.com/problems/duplicate-zeros/

給你一個長度固定的整數數組 arr,請你將該數組中出現的每個零都複寫一遍,並將其餘的元素向右平移。注意:請不要在超過該數組長度的位置寫入元素。要求:請對輸入的數組 就地 進行上述修改,不要從函數返回任何東西。

示例 1:輸入:[1,0,2,3,0,4,5,0],輸出:null,解釋:調用函數後,輸入的數組將被修改爲:[1,0,0,2,3,0,0,4]
示例 2:輸入:[1,2,3],輸出:null,解釋:調用函數後,輸入的數組將被修改爲:[1,2,3]
提示:1 <= arr.length <= 10000,0 <= arr[i] <= 9

思路

一:藉助額外空間

class Solution(object):
    def duplicateZeros(self, arr):
        """
        :type arr: List[int]
        :rtype: None Do not return anything, modify arr in-place instead.
        """
        rec, j, cnt = arr[:], 0, 0

        for i in range(len(arr)):
            if cnt > 0:
                arr[i] = 0
                cnt -= 1
            elif rec[j] == 0:
                arr[i] = 0
                j += 1
                cnt += 1
            else:
                arr[i] = rec[j]
                j += 1
        return 

二:不借助額外的空間,原址修改,做兩次遍歷,第一次遍歷確定新的列表中的最後一個元素是原列表哪個下標(last_i)對應的元素(若最後一個元素爲0,還要標記這個0是否要複寫)。第二次從右往左遍歷填入數據。

class Solution(object):
    def duplicateZeros(self, arr):
        last_i, i, two_zero = 0, 0, True
        # 第一次遍歷確定新的列表中的最後一個元素是原列表哪個下標(last_i)對應的元素
        while i < len(arr):
            if arr[last_i] != 0:
                i += 1
            else:
                i += 2
                # 若最後一個元素爲0,還要標記這個0是否要複寫
                if i > len(arr):
                    two_zero = False
            last_i += 1
            
        last_i, i = last_i - 1, len(arr) - 1

        while last_i >= 0:
            if arr[last_i] != 0:
                arr[i] = arr[last_i]
            else:
                if not two_zero and i == len(arr) -1:
                    arr[i] = 0
                else:
                    arr[i] = 0
                    i -= 1
                    arr[i] = 0
            i -= 1
            last_i -= 1

448. 找到所有數組中消失的數字

https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/

給定一個範圍在  1 ≤ a[i] ≤ n ( n = 數組大小 ) 的 整型數組,數組中的元素一些出現了兩次,另一些只出現一次。

找到所有在 [1, n] 範圍之間沒有出現在數組中的數字。您能在不使用額外空間且時間複雜度爲O(n)的情況下完成這個任務嗎? 你可以假定返回的數組不算在額外空間內。

示例:輸入:[4,3,2,7,8,2,3,1],輸出:[5,6]

思路

一:藉助額外空間,由於值域是有範圍的,可開闢一個固定空間rec,遍歷數組將nums中值作爲下標置1,遍歷rec,哪個下標爲0,就是缺失值。

class Solution(object):
    def findDisappearedNumbers(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        rec = [0] * (len(nums) + 1)

        for num in nums:
            rec[num] += 1
        res = []
        for i in range(1, len(nums) + 1):
            if rec[i] == 0:
                res.append(i)
        return res

二:同樣因爲題目值域的特殊性,且找的是缺失的數字。把 abs(nums[i])-1 索引位置的元素標記爲負數。即若該位置元素大於零,則將該位置乘上-1,nums[abs(nums[i])−1]×−1 。最後遍歷列表,若i下標的元素大於0(沒修改過),則i+1是缺失的。其實出現1次也好做,只需要將nums[abs(nums[i])−1]=nums[abs(nums[i])−1]×−1,改成nums[abs(nums[i])−1]=abs(nums[abs(nums[i])−1])×−1,找小於0的即可

class Solution(object):
    def findDisappearedNumbers(self, nums):

        for i in range(len(nums)):
            new_idx = abs(nums[i]) - 1
            if nums[new_idx] > 0:
                nums[new_idx] = -1 * nums[new_idx]

        res = []

        for i in range(len(nums)):
            if nums[i] > 0:
                res.append(i + 1)
        return res

442. 數組中重複的數據

https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/

給定一個整數數組 a,其中1 ≤ a[i] ≤ n (n爲數組長度), 其中有些元素出現兩次而其他元素出現一次。找到所有出現兩次的元素。你可以不用到任何額外空間並在O(n)時間複雜度內解決這個問題嗎?

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

思路

一:仿照上一題的解法。

class Solution(object):
    def findDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        res = []
        for i in range(len(nums)):
            new_idx = abs(nums[i]) - 1
            if nums[new_idx] < 0:
                # 小於0,表示之前遍歷過,現在又遍歷到,是解
                res.append(new_idx + 1)
            else:
                # 大於0,表示之前沒有遍歷到,此時遍歷到了標負
                nums[new_idx] = -1 * abs(nums[new_idx]) 

        return res


        

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章