二分法就不多讲了,很基础的算法,适用于排好序的数,可以提升很高的效率。
704.二分查找
执行用时:276 ms, 在所有 Python3 提交中击败了98.03%的用户
class Solution:
def search(self, nums: List[int], target: int) -> int:
low = 0
high = len(nums)-1
while(low<=high):
temp = (low+high)//2
if nums[temp]==target:
return temp
elif nums[temp]>target:
high = temp-1
elif nums[temp]<target:
low = temp+1
return -1
25.搜索插入位置
执行用时:44 ms, 在所有 Python3 提交中击败了48.98%的用户
基本上是上一道题没有修改,不过使用二分法有点慢啊。
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
low, high = 0, len(nums)-1
while(low<=high):
temp = (low+high)//2
if nums[temp]==target:
return temp
elif nums[temp]>target:
high = temp-1
elif nums[temp]<target:
low = temp+1
return low
162.查找峰值。
这道题比较难(中等难度的对于我这种小白来说就是难的了),一开始还是没做出来,看了官方给的解题思路。
力扣的描述是:
峰值元素是指其值大于左右相邻值的元素。
给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。
数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞。
而且要求了O(logN)的时间复杂度。
看题目:
1.只要找到一个峰值就可以
2.相邻元素不相等
3.nums[-1] = nums[n] = -∞
这样三个条件。
一开始我写代码的时候,总是以nums[i-1]<nums[i] > nums[i+1]作为峰值的判别条件,从而导致列表的两端很难处理,总是溢出,需要进行很多条件判断,越写越长,代码逐渐复杂了起来,想来应该不会出这么没有营养的题目,就没忍住看了答案(哭)。
官方解答中,最重要的一点就是可以通过只比较nums[i] 和 nums[i+1]的大小,就能达到判断的目的。
取i为当前要处理的列表的中点,考虑如下几种情况:
- nums[i] > nums[i+1]
此时,将游标从中点[i]向右侧移动,值是下降的;
又因为nums[-1]可以看作负无穷,所以将游标从[-1]向右移动,值必然是上升的;
所以在列表的左半部分,[0, i+1]中(两侧都包含,因为i可能是峰值)值先上升在下降,必然存在一个峰值。 - nums[i] < nums[i+1]
此时,将游标从中点[i]向右侧移动,值是上升的;
又因为nums[n]可以看作负无穷,所以将游标从[n]向左移动,值必然是上升的;
所以在列表的右半部分,(i, n-1]中(左侧i不包含,因为i必然不可能是峰值)值先上升在下降,必然存在一个峰值。
很容易想到,这里应该使用递归,但是我还没学到递归,就暂时用迭代写了一下。
可见做算法题主要还是思路。
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
left,right = 0,len(nums)-1
while(left<=right):
if left == right:
return left
temp = (left+right)//2
if nums[temp]>nums[temp+1]:
right = temp
elif nums[temp]<nums[temp+1]:
left = temp+1 ##+1抛弃无用值,而且如果left和right都不+-1的话,最终left无法等于right,会无限循环。
然后是74题,搜索二维矩阵。
这道题也是比较简单的,读题可以了解到,如果将矩阵铺平,其实就是一个已经排好序的列表,我们完全可以套用之前的代码,只不过将temp进行一下换算就可以满足要求。
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
## 这里排除了一个特殊情况,因为如果是空矩阵,下面的代码会报错
if(len(matrix)==0):
return False
## 获取矩阵的维度,如果用numpy的话应该是matrix.shape
m, n = len(matrix), len(matrix[0])
length = m*n ##计算总长度
left, right = 0, length-1
while(left <= right):
temp = (left+right)//2
## 与前面的代码相比只有这里不一样,将长度换算为行列数
x = temp // n
y = temp % n
if matrix[x][y] == target:
return True
elif matrix[x][y] > target:
right = temp-1
elif matrix[x][y] < target:
left = temp+1
return False
好啦,二分法就先做这几道题。