744. 寻找比目标字母大的最小字母
给定一个只包含小写字母的有序数组letters 和一个目标字母 target,寻找有序数组里面比目标字母大的最小字母。
数组里字母的顺序是循环的。举个例子,如果目标字母target = 'z' 并且有序数组为 letters = ['a', 'b'],则答案返回 'a'。
示例:
输入:letters = ["c", "f", "j"]target = "a"输出: "c"
输入:letters = ["c", "f", "j"]target = "c"输出: "f"
输入:letters = ["c", "f", "j"]target = "d"输出: "f"
输入:letters = ["c", "f", "j"]target = "g"输出: "j"
输入:letters = ["c", "f", "j"]target = "j"输出: "c"
输入:letters = ["c", "f", "j"]target = "k"输出: "c"注:
letters长度范围在[2, 10000]区间内。letters 仅由小写字母组成,最少包含两个不同的字母。目标字母target 是一个小写字母。
二分法,比较绕一点了
charnextGreatestLetter(vector<char>&letters, chartarget) {
intl=0;
intr=letters.size() -1;
while (l<=r)
{
intmid= (l+r) /2;
if (target<letters[mid])//确切大于了,右侧再向后退
r=mid-1;
else
l=mid+1;//即使是等于,也依然向前走
}
returnletters[l%letters.size()];//到最后节点了,返回第一个元素
}
执行用时 :8 ms, 在所有 C++ 提交中击败了99.29%的用户
内存消耗 :9.1 MB, 在所有 C++ 提交中击败了78.92%的用户
704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9输出: 4解释: 9 出现在 nums 中并且下标为 4示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2输出: -1解释: 2 不存在 nums 中因此返回 -1
提示:
你可以假设 nums 中的所有元素是不重复的。n 将在 [1, 10000]之间。nums 的每个元素都将在 [-9999, 9999]之间。
intsearch(vector<int>&nums, inttarget) {
intmid=0, low=0, high=nums.size() -1;
while (low<high) {
mid=low+ (high-low) /2;
if(nums[mid]==target)
{
returnmid;
}
elseif (nums[mid] <target) {
low=mid+1;
}
else
{
high=mid-1;
}
}
if (nums[low] ==target) returnlow;
else
return-1;
}
执行用时 :68 ms, 在所有 C++ 提交中击败了38.93%的用户
内存消耗 :11 MB, 在所有 C++ 提交中击败了69.09%的用户
第二种,二分法经典模板三解析
循环中止条件为 start < end,代表差值为1的时候就中止了同时start = mid;end = mid;这就代表,如果搜寻到start和end相差为1的时候,循环就已经停止,所以需要在循环结束后继续判断
个人比较喜欢用模版三,因为更加清晰易理解,后面如果需要基于此修改的时候,也更能够想清楚。
intsearch(vector<int>&nums, inttarget) {
intstart=0;
intend=nums.size() -1;
while (start+1<end) {
//start和end差值为1的时候,直接就中止了。
intmid=start+ (end-start) /2;
if (nums[mid] <target) {
start=mid;
}
else {
end=mid;
}
}
if (nums[start] ==target) {
//因为差值为1的时候,直接就中止了,所以,需要判断start和end
returnstart;
}
if (nums[end] ==target) {
//因为差值为1的时候,直接就中止了,所以,需要判断start和end
returnend;
}
return-1;
}
二分法经典模板一解析
循环中止条件为 start <= end,代表差值为1和0的时候都会继续循环。代码相应的处理方法就是start = mid + 1;end = mid - 1;
intsearch(vector<int>&nums, inttarget) {
if (nums.size() ==0) {
return-1;
}
intstart=0;
intend=nums.size() -1;
while (start<=end) {
//差值为1的时候,mid优先等于start
//差值为0的时候,还会继续循环
intmid=start+ (end-start) /2;
if (nums[mid] ==target) {
returnmid;
}
elseif (nums[mid] <target) {
//差值为1的情况下,mid比target小,加一/
//差值为0的情况下,mid比target小,加一则结束
start=mid+1;
}
else {
//差值为1的情况下,mid比target大,那么减一
//差值为0的情况下,mid比target大,减一则结束
end=mid-1;
}
}
return-1;
}