leetcode笔记|第九周 二分法

第九周 二分

35 搜索插入位置

输入: [1,3,5,6], 5 输出: 2。

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        # 暴力法
        # if nums[0]>target: return 0
        # for i in range(len(nums)):
        #     if nums[i]==target:
        #         return i
        #     if nums[i]>target and nums[i-1]<target:
        #         return i
        # return len(nums)

        # 插入后返回idx
        # if target in nums:
        #     return nums.index(target)
        # nums.append(target)
        # nums.sort()
        # return nums.index(target)

        # 二分法!!!
        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

34 在排序数组中查找元素的第一个和最后一个位置

输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4]

输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1]

肯定得用二分法,才能时间复杂度n(logN)

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        if target not in nums:  # 没有就不用遍历了
            return [-1, -1]
        res=[]
        left, right=0, len(nums)-1
        while left<=right:  # 注意有等号才不会报错
            mid = left + (right-left)//2
            if nums[mid]<target:
                left = mid+1
            elif nums[mid]>target:
                right = mid-1
            else:
                res.append(mid)
                left = mid+1 # 两遍,对称
        left, right=0, len(nums)-1
        while left<=right:
            mid = left + (right-left)//2
            if nums[mid]<target:
                left = mid+1
            elif nums[mid]>target:
                right = mid-1
            else:
                res.append(mid)
                right = mid-1
        res.sort()  # 排序
        return [res[0],res[-1]]

33 搜索旋转排序数组

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        if target not in nums:
            return -1
        return nums.index(target) # 暴力查找list中target的idx
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        if target not in nums:
            return -1
        # return nums.index(target)
        l, r =0, len(nums)-1
        while l <= r:
            mid = (l+r)//2
            if nums[mid]==target:
                return mid
            if nums[0]<=nums[mid]:  # 等号没加又错了 二分法简单但是细节好容易错
                if nums[0]<=target<nums[mid]:
                    r = mid-1
                else:
                    l = mid+1
            else:
                if nums[mid]<target<=nums[len(nums)-1]:
                    l = mid+1
                else:
                    r = mid-1
        return -1

162 寻找峰值

输入: nums = [1,2,1,3,5,6,4] 输出: 1 或 5 。复杂度要求O(logN),想到用二分法,但一看是无序的,就不知道怎么做了。其实只要找到一个就好了,那么

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

74 搜索二维矩阵

二维矩阵的检索:row,col = mid // n,mid % n

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        m = len(matrix)
        if m==0:
            return False
        n = len(matrix[0])
        left, right = 0, m * n - 1
        while left<=right:
            mid = (left+right) // 2
            ele = matrix[mid // n][mid % n]
            if ele == target:
                return True
            else:
                if ele>target:
                    right = mid - 1
                else:
                    left = mid + 1
        return False

240 搜索二维矩阵II

也是给定matrix和target,查询target是否在matrix里。但是数组横着递增,竖着递增。

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]

class Solution:
    def searchMatrix(self, matrix, target):
        row , col = len(matrix)-1, 0 # trick:左下角,往上减小,往右增加。
        if matrix == []:
            return False
        while row>=0 and col <= len(matrix[0])-1:
            if matrix[row][col] == target: 
                return True
            else:
                if matrix[row][col]>target:
                    row -= 1
                else:
                    col += 1
        return False

1552 两球之间的磁力

要反向思维了奥,从答案出发二分。

class Solution:
    def maxDistance(self, position: List[int], m: int) -> int:
        
        def check(x): # 如果每隔x防止一个球,能否放够m个?能,则答案>=x
            pre = position[0]
            cnt = 1
            for i in range(1, len(position)):
                if position[i]-pre >= x:
                    pre = position[i]
                    cnt += 1
            return cnt >= m
        
        # 如果距离为3可以,那么1和2都可以,但是4+都不可以。所以可以使用二分法,答案最小1,最大max-min。
        # 如果mid可以,代表[1,mid-1]都可以,答案从[mid+1, max]之间找。
        position.sort()
        left, right, ans = 1, position[-1]-position[0], -1
        while left <= right: # 二分法标志就是这个while 不要忘记写他!
            mid = (left+right)//2
            if check(mid):
                ans = mid
                left = mid + 1
            else:
                right = mid -1
        return ans

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值