程式碼隨想錄Day1 | LeetCode 704. 二分查詢、LeetCode 27. 移除元素、LeetCode 977. 有序陣列的平方

溺死在幸福里的猪發表於2024-09-13

LeetCode 704. 二分查詢

核心:明白[left, right] 和 [left, right)兩種迴圈不變數

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1  # [left, right]
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] < target:
                left = mid + 1
            elif nums[mid] > target:
                right = mid - 1
            else:
                return mid
        return -1
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)  # [left, right)
        while left < right:
            mid = left + (right - left) // 2
            if nums[mid] < target:
                left = mid + 1
            elif nums[mid] > target:
                right = mid 
            else:
                return mid
        return -1

有關二分法其他經典題目:

LeetCode 35. 搜尋插入位置

這道題實際上就是查詢target的最左側位置,如果沒有就是第一個大於target的位置

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return left
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)
        while left < right:
            mid = left + (right - left) // 2
            if nums[mid] < target:
                left = mid + 1
            else:
                right = mid
        return left

LeetCode 34. 在排序陣列中查詢元素的第一個和最後一個位置

這一題就是“二分查詢”集大成者

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        def _left():
            left, right = 0, len(nums) - 1
            while left <= right:
                mid = left + (right - left) // 2
                if nums[mid] < target:
                    left = mid + 1
                else:
                    right = mid - 1
            if left == len(nums):
                return -1
            if nums[left] != target:
                return -1
            return left
        
        def _right():
            left, right = 0, len(nums) - 1
            while left <= right:
                mid = left + (right - left) // 2
                if nums[mid] > target:
                    right = mid - 1
                else:
                    left = mid + 1
            if right == -1:
                return -1
            if nums[right] != target:
                return -1
            return right
        return [_left(), _right()]

LeetCode 33. 搜尋旋轉排序陣列

有關“二分查詢”的主要變式
要注意if nums[mid] >= nums[left]中的“=”需要算在左崖上

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return mid
            if nums[mid] >= nums[left]:
                if nums[mid] > target and target >= nums[left]:
                    right = mid -1 
                else:
                    left = mid + 1
            else:
                if nums[mid] < target and target <= nums[right]:
                    left = mid + 1
                else:
                    right = mid - 1
        return -1

LeetCode 74. 搜尋二維矩陣

LeetCode 153. 尋找旋轉排序陣列中的最小值

LeetCode 4. 尋找兩個正序陣列的中位數

LeetCode 27. 移除元素

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        slow, fast = 0, 0
        while fast < len(nums):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        return slow

977. 有序陣列的平方

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left, right = 0, len(nums) - 1
        res = [None] * len(nums)
        p = len(nums) - 1
        while left <= right:
            if abs(nums[left]) < abs(nums[right]):
                res[p] = nums[right] ** 2
                right -= 1
            else:
                res[p] = nums[left] ** 2
                left += 1
            p -= 1
        return res

相關文章