阶梯训练3-二分查找
Posted zlldt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阶梯训练3-二分查找相关的知识,希望对你有一定的参考价值。
昨天没做完的:
31. 数组划分
给出一个整数数组 nums 和一个整数 k。划分数组(即移动数组 nums 中的元素),使得:
所有小于k的元素移到左边
所有大于等于k的元素移到右边
返回数组划分的位置,即数组中第一个位置 i,满足 nums[i] 大于等于 k。
样例
给出数组 nums = [3,2,2,1]
和 k = 2
,返回 1
.
定义指针start,end,count记录小于k的元素个数。
start, end = 0, len(nums) - 1
count = 0
在start<end条件下:
如果nums[start]<k,start加一,count加一,
while start <= end:
while start <= end and nums[start] < k:
start += 1
count += 1
如果start、end位置值都大于等于k,end减一,
if start <= end and nums[start]>=k and nums[end]>=k:
end -= 1
如果start位置值大于等于k,end位置小于k,交换2个位置的值,start加一,end减一,count加一。
这样应该包括了所有的情况,执行如下:
代码:
看看二分查找的题目:
14. 二分查找
给定一个排序的整数数组(升序)和一个要查找的整数target
,用O(logn)
的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1
。
样例
在数组 [1, 2, 3, 3, 4, 5, 10]
中二分查找3
,返回2
。
如果target小于第一个整数或者大于最后一个,直接返回-1,
length = len(nums)
if target<nums[0] or target>nums[length-1]:
return -1
left,right设置为0,length,
如果中间位置元素小于target,则将mid设置为left,在mid与right范围内查找,
如果大于target,则在left与mid范围内查找。
left, right = 0, length
while left + 1 < right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid
else:
right = mid
如果nums[left]等于target,返回left,否则返回right。
if nums[left] == target :
return left
elif nums[right] == target :
return right
运行结果:
74. 第一个错误的代码版本
代码库的版本号是从 1 到 n 的整数。某一天,有人提交了错误版本的代码,因此造成自身及之后版本的代码在单元测试中均出错。请找出第一个错误的版本号。
你可以通过 isBadVersion
的接口来判断版本号 version 是否在单元测试中出错,具体接口详情和调用方法请见代码的注释部分。
样例
给出 n=5
调用isBadVersion(3)
,得到false
调用isBadVersion(5)
,得到true
调用isBadVersion(4)
,得到true
此时我们可以断定4
是第一个错误的版本号
这个数组1-n的值是false,false,false,true,true,即要查找第一个true的位置,套用上面的二分查找。
如果mid位置是false,则在后半部分查找,将mid设置为start,
如果mid位置是true,则在前半部分查找,将mid设置为end。
start, end = 1, n
while start + 1 < end:
mid = (start + end)//2
if SVNRepo.isBadVersion(mid):
end = mid
else:
start = mid
如果start位置为错误版本,返回start位置,否则返回end位置。
if SVNRepo.isBadVersion(start):
return start
return end
以上是关于阶梯训练3-二分查找的主要内容,如果未能解决你的问题,请参考以下文章
代码随想录算法训练营第一天 | 704. 二分查找27. 移除元素