前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode-算法-二分查找-第15天

LeetCode-算法-二分查找-第15天

作者头像
布衣者
发布2021-09-07 11:41:34
2280
发布2021-09-07 11:41:34
举报
文章被收录于专栏:布衣者博客

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

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。

示例 1: 输入:nums = [5,7,7,8,8,10], target = 8 输出:[3,4] 示例 2: 输入:nums = [5,7,7,8,8,10], target = 6 输出:[-1,-1] 示例 3: 输入:nums = [], target = 0 输出:[-1,-1]

具体题目链接

Python

代码语言:javascript
复制
class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        left,right=0,len(nums)-1
        def searchRange(left,right,target):
            while left<=right:
                mid=left+(right-left)//2
                if nums[mid]>=target:
                    right=mid-1
                else:
                    left=mid+1
            return left
        a=searchRange(left,right,target)
        if a>right or nums[a]!=target:
            return [-1,-1]
        b=searchRange(a,right,target+1)
        return [a,b-1]

思路:二分法查找,因为要找到要找的元素的首位和最后一位,为了代码复用,因此通过查找target和target+1来确定首位和最后一位。二分法是变种,if nums[mid]>=target保证右边界一直推到首位前一位,而左边界则仅进位到首位位置。

代码语言:javascript
复制
        length=len(nums)
        a=bisect.bisect_left(nums, target, lo=0, hi=length)
        if a==length or nums[a]!=target:
            return [-1,-1]
        b=bisect.bisect_right(nums, target, lo=0, hi=length)-1
        return [a,b]

思路:通过调用库来实现,bisect.bisect_left寻找该值最左侧下标,bisect.bisect_right寻找最后一位的下一位下标。

GO

代码语言:javascript
复制
func searchRange(nums []int, target int) []int {
    a:=sort.SearchInts(nums,target)
    if a==len(nums) || nums[a]!=target{
        return []int{-1,-1}
    }
    b:=sort.SearchInts(nums,target+1)-1
    return []int{a,b}
}

思路:同理,调用sort.SearchInts模块。

33. 搜索旋转排序数组

整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。 给你旋转后的数组nums和一个整数target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

示例 1: 输入:nums = [4,5,6,7,0,1,2], target = 0 输出:4 示例 2: 输入:nums = [4,5,6,7,0,1,2], target = 3 输出:-1 示例 3: 输入:nums = [1], target = 0 输出:-1

具体题目链接

Python

代码语言:javascript
复制
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
            elif nums[0]<=nums[mid] :
                if nums[left] <= target < nums[mid]:
                    right=mid-1
                else:
                    left=mid+1      
            else:
                if nums[mid]<target<=nums[right]:
                    left=mid+1
                else:
                    right=mid-1
        return -1

思路:因为整个数组来说并不是有序的,是两个有序片段,nums=[nums1,nums2],但符合以下规律nums1的首位大于nums2的末尾。 要确定target的位置,首先要解决的问题就是判断target在哪个片段。因此我们先通过nums[0]<=nums[pviot]进行判断,当前指针的位置,若为True,则证明pviot在片段nums1[0,mid]之中。之后通过nums[left] <= target < nums[mid]来判断target 位置范围,从而逐步获取。若为False,则证明在nums1[mid+1:]+nums2中,因此同理,通过逐步缩小范围实现获取target。

GO

代码语言:javascript
复制
func search(nums []int, target int) int {
    left,right,mid:=0,len(nums)-1,0
    for left<=right{
        mid=left+(right-left)/2
        if nums[mid]==target{
            return mid
        }else if nums[0]<=nums[mid]{
            if nums[left]<=target && target<nums[mid]{
                right=mid-1
            }else{
                left=mid+1
            }
        }else{
            if nums[mid]<target && target<=nums[right]{
                left=mid+1
            }else{
                right=mid-1
            }
        }
    }
    return -1
}

思路:同python

74. 搜索二维矩阵

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性: 每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。

示例 1: 输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 输出:true 示例 2: 输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 输出:false

具体题目链接

Python

代码语言:javascript
复制
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        left,list_r,list_c=0,len(matrix),len(matrix[0])
        right=list_c*list_r-1
        while left<=right:
            mid=left+(right-left)//2
            mid_r,mid_c=divmod(mid,list_c)
            if matrix[mid_r][mid_c]==target:
                return True
            if matrix[mid_r][mid_c]<target:
                left=mid+1
            else:
                right=mid-1
        return False

思路:将矩阵降维,降低为1维度就能实现标准二分法。

代码语言:javascript
复制
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        left,right=0,len(matrix)-1
        while left<right:
            mid=left+(right-left+1)//2
            if matrix[mid][0]<=target:
                left=mid
            else:
                right=mid-1
        left_c,right_c=0,len(matrix[left])-1
        while left_c<=right_c:
            mid=left_c+(right_c-left_c)//2
            if matrix[left][mid]==target:
                return True
            elif matrix[left][mid]<target:
                left_c=mid+1
            else:
                right_c=mid-1
        return False

思路:充分利用性质:每行的第一个整数大于前一行的最后一个整数,则我们先进行搜索每一行的第一列,找到第一个最后一个小于等于target的行,之后在该行进行搜索,因此用了两次二分法。

GO

代码语言:javascript
复制
func searchMatrix(matrix [][]int, target int) bool {
    left,right,mid:=0,len(matrix)-1,0
    for left<right{
        mid=left+(right-left+1)/2
        if matrix[mid][0]<=target{
            left=mid
        }else{
            right=mid-1
        }
    }
    left_c,right_c:=0,len(matrix[left])-1
    
    for left_c<=right_c{
        mid=left_c+(right_c-left_c)/2
        if matrix[left][mid]==target{
            return true
        }else if matrix[left][mid]>target{
            right_c=mid-1
        }else{
            left_c=mid+1
        }
    }
    return false
}

思路:同python

代码语言:javascript
复制
func searchMatrix(matrix [][]int, target int) bool {
    row:=sort.Search(len(matrix),func(i int) bool{return target<matrix[i][0]})-1
    if row<0{
        return false
    }
    mid:=sort.SearchInts(matrix[row],target)
    return mid<len(matrix[row]) && matrix[row][mid]==target

思路:通过sort.Search找到当前行,再通过sort.SearchInts进行二分搜索。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年08月16日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 34. 在排序数组中查找元素的第一个和最后一个位置
    • Python
      • GO
      • 33. 搜索旋转排序数组
        • Python
          • GO
          • 74. 搜索二维矩阵
            • Python
              • GO
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档