剑指 Offer 53 - II. 0~n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
示例 1:
输入: [0,1,3]
输出: 2
示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8
限制:
1 <= 数组长度 <= 10000
解法一:
二分设置left=0,right=nums.length-1,以及mid。
如果(left,mid]之间有缺失数字,则有
nums[mid]-nums[left] != mid - left;
则令right=mid(因为此时的mid仍有可能是缺失数字后的第一位)
如果(left,mid]之间没有,则说明缺失数字在(mid, right],
则令left=mid(因为此时的mid不可能是缺失数字后的第一位)
接下来确定while()的内容。我们想要的是情况是(左,右], 左是正常,右是缺失后的一位。故设定while内容 left+1<right
返回内容是nums[right]=right+1,故缺失数字为right。
但是这个思路有bug,即当缺失数字为0和n时,不能够确定。所以需要提前判断。
总的代码为:
class Solution {
public int missingNumber(int[] nums) {
int left = 0;
int right = nums.length-1;
if(nums[0]!=0) return 0;
if(nums[right]!=right+1) return right+1;
while(left+1<right){
int middle = left + (right-left)/2;
if(nums[middle]-nums[left] == middle-left){
left = middle;
}else{
right=middle;
}
}
return right;
}
}
思路2:
如果没有缺失数字,则有nums[i]=i
;故题目的目的就是找出第一个nums[i]!=i
的数字。
设置left=0,right=nums.length;
有效区间为[left, right]
如果有nums[mid]=mid
,则说明[left,mid]段内ok,错误在(mid,right]内,令left = mid + 1;
否则,说明[left, mid]内不ok,令right = mid
定义left<right
返回right
class Solution {
public int missingNumber(int[] nums) {
int left = 0;
int right = nums.length;
while(left<right){
int mid = left + (right-left) / 2;
if(nums[mid]==mid){
left = mid + 1;
}else{
right = mid;
}
}
return right;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理