六十七、Leetcode數組系列(下篇)

@Author:Runsen
@Date:2020/6/19

人生最重要的不是所站的位置,而是內心所朝的方向。只要我在每篇博文中寫得自己體會,修煉身心;在每天的不斷重複學習中,耐住寂寞,練就真功,不畏艱難,奮勇前行,不忘初心,砥礪前行,人生定會有所收穫,不留遺憾 (作者:Runsen )

作者介紹:Runsen目前大三下學期,專業化學工程與工藝,大學沉迷日語,Python, Java和一系列數據分析軟件。導致翹課嚴重,專業排名中下。.在大學60%的時間,都在CSDN。決定今天比昨天要更加努力。
前面文章,點擊下面鏈接

我的Python教程,不斷整理,反覆學習

今日,我決定繼續更新Python教程,今天就見識下刷Leetcode的快樂。

Runsen先打開Pycharm,開始繼續嗨起來

劍指 Offer 系列 面試題11 - 旋轉數組的最小數字

先來一個簡單的,見面禮。題目來源於 LeetCode 上的面試題11:旋轉數組的最小數字

題目鏈接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/

#把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如,數組 [3,4,5,1,2] 爲 [1,2,3,4,5] 的一個旋轉,該數組的最小值爲1。 
# 示例 1: 
# 輸入:[3,4,5,1,2]
#輸出:1
# 示例 2: 
# 輸入:[2,2,2,0,1]
#輸出:0
# 注意:本題與主站 154 題相同:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/ 
# Related Topics 二分查找

初看題目最直觀的解法並不難,直接尋找,我們不難寫出如下代碼。

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        return min(numbers)

時間複雜度O(n)O(n),空間複雜度O(1)O(1)。因此這樣是不行的

考的是:二分查找。二分法的分析我們知道,數組可以分爲前後兩個遞增數組

  • numbers[mid] > numbers[high]時,說明最小值在mid的右邊,縮小範圍low = mid + 1
  • numbers[mid] == numbers[high]時,我們不知道最小值的範圍,但是可以肯定的是去除numbers[high]是沒有影響的,縮小範圍high -= 1
  • numbers[mid] < numbers[high]時,我們知道最小值的不是numbers[mid]]就是在mid的左邊,縮小範圍high = mid
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        l, r = 0, len(numbers) - 1
        while l < r:
            mid = (l + r) // 2
            if numbers[mid] > numbers[r]:
                l = mid + 1
            elif numbers[mid] < numbers[r]:
                r = mid
            else:
                r -= 1
        return numbers[l]


面試題53 - II. 0~n-1中缺失的數字

#一個長度爲n-1的遞增排序數組中的所有數字都是唯一的,並且每個數字都在範圍0~n-1之內。在範圍0~n-1內的n個數字中有且只有一個數字不在該數組中,請找出這個數字。 
# 示例 1: 
# 輸入: [0,1,3]
#輸出: 2
# 示例 2: 
# 輸入: [0,1,2,3,4,5,6,7,9]
#輸出: 8 
# 限制: 
# 1 <= 數組長度 <= 10000 
# Related Topics 數組 二分查找

對於有序數組或者多部分有序數組的查找問題99.999999%都是用二分查找,這道題其實考察的是二分查找的兩個常見拓展之一,即查找目標序列的左邊界,另一個常見拓展是查找目標序列的右邊界。

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        i, j = 0, len(nums) - 1
        while i <= j:
            m = (i + j) // 2
            if nums[m] == m: 
            	i = m + 1
            else: 
            	j = m - 1
        return i

LeetCode 第 66題:加一

#給定一個由整數組成的非空數組所表示的非負整數,在該數的基礎上加一。 
# 最高位數字存放在數組的首位, 數組中每個元素只存儲單個數字。 
# 你可以假設除了整數 0 之外,這個整數不會以零開頭。 
# 示例 1: 
# 輸入: [1,2,3]
#輸出: [1,2,4]
#解釋: 輸入數組表示數字 123。

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

一次for循環解決問題,從數組尾部遍歷,如果遇到數字不是9就+1,並返回。如果是9,則將當前數字置0,並進入下一輪循環

考慮特殊情況:9999,此時需要檢查最後一次for循環的數字是不是0,即digits[0]是否爲0,如果是0,則遇到了特殊情況。此時需要在數組最前面加一個數字1,然後返回即可

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        for i in range(len(digits)-1, -1, -1):
            if digits[i] < 9:
                digits[i] += 1
                return digits
            digits[i] = 0
        return [1] + digits

先將數字列表數組轉化爲數字或者字符串,然後+1,最後將數字轉化爲數組,並返回

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        ##先變成一個整的數字,然後做加法,然後轉換成str,再轉int加到新的list中
        nums_str = ""
        for i in digits:
            nums_str =nums_str+str(i)
    
        nums_int = int(nums_str)+1
        res = []
        for i in str(nums_int):
            res.append(int(i))
        return res

		 # a = [i * 10 ** index for index, i in enumerate(digits[::-1])]
		 # num = sum(a) + 1
		 # print(num)
		 # return [int(x) for x in str(num)]

面試題53 - I. 在排序數組中查找數字的次數 I

#統計一個數字在排序數組中出現的次數。 
# 示例 1: 
# 輸入: nums = [5,7,7,8,8,10], target = 8
#輸出: 2 
# 示例 2: 
# 輸入: nums = [5,7,7,8,8,10], target = 6
#輸出: 0 
# 限制: 
# 0 <= 數組長度 <= 50000 
# 注意:本題與主站 34 題相同(僅返回值不同):https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/ 
# Related Topics 數組 二分查找

python:首先爲了達到目的,我們看使用python最容易實現的操作

 if len(nums) ==0:
    return 0
 else:
    return nums.count(target)


更好的(根據二分法思想)實現下所示:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        # 雙指針
        l = 0
        r = len(nums) - 1
        while l <= r:
            if nums[l] < target:
                l += 1
            elif nums[r] > target:
                r -= 1
            elif nums[l] == nums[r] == target:
                return r - l + 1
        return 0


leetcode977:有序數組的平方

#給定一個按非遞減順序排序的整數數組 A,返回每個數字的平方組成的新數組,要求也按非遞減順序排序。 
# 示例 1: 
# 輸入:[-4,-1,0,3,10]
#輸出:[0,1,9,16,100]
# 示例 2: 
# 輸入:[-7,-3,2,3,11]
#輸出:[4,9,9,49,121]
# 提示: 
# 1 <= A.length <= 10000 
# -10000 <= A[i] <= 10000 
# A 已按非遞減順序排序。 
# Related Topics 數組 雙指針

利用python中的列表生成式生成求平方後的數組,利用python中的排序函數sorted()對求平方後的數組進行排序。

return sorted([k**2 for k in A])

時間複雜度:利用列表生成式生成求平方後的數組,時間複雜度爲O(N)O(N),python中排序用的是蒂姆排序算法,時間複雜度爲O(NlogN)O(NlogN),所以該算法的時間複雜爲O(NlogN)O(NlogN)

空間複雜度:O(N)O(N)。利用列表生成式生成求平方後數組的時間複雜度爲O(N)O(N),蒂姆排序空間複雜度爲O(N)O(N),所以該算法空間複雜度爲O(N)O(N)

下面就是常見的雙指針做法

class Solution:
    def sortedSquares(self, A: List[it]) -> List[int]:
        left,right,result = 0, len(A) - 1,[]
        while left <= right:
            if abs(A[left]) > abs(A[right]):
                result.insert(0, pow(A[left],2))
                left += 1
            else:
                result.insert(0, pow(A[right],2))
                right -= 1
        return result
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章