力扣-数组-二分法

 

题目顺序

704二分查找,35搜索插入位置,34排序数组中查找元素首位和末位,69求平方根,367有效的完全平方数。

解题思路

比暴力循环法更优的解法是二分法

(1)确定初始左右边界

(2)注意二分时[left, right]都是闭区间(个人选择)

(3)实例推算,确定终止条件

 

例题

 

 

 

复制代码
 1 class Solution(object):
 2     def search(self, nums, target):
 3         """
 4         :type nums: List[int]
 5         :type target: int
 6         :rtype: int
 7         """
 8         ## 暴力循环法
 9         # for i in range(len(nums)):
10         #     if target==nums[i]:
11         #         return i
12         #     if nums[i]>target or i==len(nums)-1:
13         #         return -1
14 
15         ## 二分查找法
16         ## 注意划分边界和终止条件,最好的方法就是实例,然后总结
17         left = 0
18         right = len(nums)-1
19    
20         while(1):
21             mid = (left+right) // 2
22             if left>=right and nums[left]!=target:
23                 return -1
24             if target==nums[mid]:
25                 return mid
26             elif target<nums[mid]: # 这里写成mid-1,但是这样左右区间合起来就不是原区间了,少了mid值;也可以写成mid,终止条件可以是left==right
27                 right = mid - 1
28             elif target>nums[mid]:
29                 left = mid + 1
复制代码

 

更多练习

 

 

  

复制代码
 1 class Solution(object):
 2     def searchInsert(self, nums, target):
 3         """
 4         :type nums: List[int]
 5         :type target: int
 6         :rtype: int
 7         """
 8         # 直接二分查找
 9         left = 0
10         right = len(nums)-1
11         while(1):
12             mid = (left+right) // 2
13             if nums[mid]==target:
14                 return mid
15             elif left>=right and nums[left]<target:
16                 return left+1
17             elif left>=right and nums[left]>target:
18                 return left
19             if nums[mid]>target:
20                 right = mid-1
21             if nums[mid]<target:
22                 left = mid+1
复制代码

 

# 搜索插入相比之下,在没有找到需要插入的时候,多了一个判断left和target的条件

 

 

 

 

 

复制代码
 1 class Solution(object):
 2     def searchRange(self, nums, target):
 3         """
 4         :type nums: List[int]
 5         :type target: int
 6         :rtype: List[int]
 7         """
 8         # 先二分查找元素,找到滑动寻找窗口,没找到返回[-1,-1]
 9         def erfen(nums, target):
10             left = 0
11             right = len(nums)-1
12             while(left<=right):
13                 mid = (left+right) // 2
14                 if nums[mid]==target:
15                     return mid
16                 elif nums[mid]>target:
17                     right = mid - 1
18                 elif nums[mid]<target:
19                     left = mid + 1
20             return -1
21 
22         lb = erfen(nums, target)
23         if lb==-1:
24             return [-1,-1]
25         else:
26             l, r = lb, lb
27             while l-1>=0 and nums[l-1]==target:
28                 l -= 1
29             while r+1<=len(nums)-1 and nums[r+1]==target:
30                 r += 1
31             return [l,r]
复制代码

 

 

 

复制代码
 1 class Solution(object):
 2     def mySqrt(self, x):
 3         """
 4         :type x: int
 5         :rtype: int
 6         """
 7         # 二分法
 8         if x==0 or x==1:
 9             return x
10         # 4,2  5,2.5 
11         left = 0
12         right = x
13         while left<=right:
14             mid = (left+right)//2
15             if mid * mid==x or (mid*mid-x)*((mid+1)*(mid+1)-x)<0:
16                 return mid
17             elif (mid*mid-x)*((mid-1)*(mid-1)-x)<0:
18                 return mid-1
19             # elif (mid*mid-x)*((mid+1)*(mid+1)-x)<0:
20             #     return mid
21             if mid*mid>x:
22                 right = mid-1
23             elif mid*mid<x:
24                 left = mid+1
复制代码

# 通过二分法找非负整数的平方根,注意是从2开始的,注意return的截止条件,可以先按思路罗列,进而整理代码。

 

 

复制代码
 1 class Solution(object):
 2     def isPerfectSquare(self, num):
 3         """
 4         :type num: int
 5         :rtype: bool
 6         """
 7         # 二分查找法,类似题目69
 8         left = 0
 9         right = num
10         while(left<=right):
11             mid = (left+right) // 2
12             if mid*mid==num:
13                 return True
14             elif (mid*mid-num)*((mid-1)*(mid-1)-num)<0 or (mid*mid-num)*((mid+1)*(mid+1)-num)<0:
15                 return False
16             if mid*mid>num:
17                 right = mid-1
18             else: left = mid+1
复制代码

 

posted @   Yalking  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示