二分法 经典应用案例之 0~n-1中缺失的数字

题目描述

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0到n-1之内。在范围0到n-1的n个数字中有且只有一个数字不在该数组中,请找出这个数字。(题目来源:《剑指offer》53题)

思路

解法1 时间复杂度O(n):
首先可以对0 ~ (n~1)这n个数求和S1,然后对数组中的所有数求和S2,二者的差值S1-S2即为不在数组中的这个数!
缺点:没用利用好数组是递增排序的规律,复杂度为O(n),这里不再赘述。

解法2 时间复杂度O(log n):
假设数字m不在数组中,由于数组是排序的,所以m之前的数字在数组中的值与其下标应相等,m之后的值其值比下标都要大1,因此,我们要找的不在数组中的元素m就是数组中的第一个数值与下标不等的下标!由于数组是递增排序的,因此利用二分法!

二分法代码


int getMissingNumber(vector<int>& nums) {
		if (nums.size() <= 0)
			return 0;

		int l = 0;
		int r = nums.size() - 1;
/***************经典二分代码***************/
		while (l < r) {
			int mid = (l + r) / 2;
			if (nums[mid] != mid) 	//每次使用时只需注意if条件语句满足什么条件时收缩右边界即可
				r = mid;
			else
				l = mid + 1;
		}						//无论找到找不到最后都收缩于l=r的情况
/***************经典二分代码***************/
		if (nums[l] == l)		//最后判断一下是否找到了想要的结果:如果没找到,说明收缩在数组的最右侧边界处,此时结果应为下标+1********注意边界情况
			return l + 1;
		else					//如果找到了直接返回下标1即可
			return l;
	}
	

经典二分模板:


while (l < r) {
			int mid = (l + r) / 2;
			if (/*此处填写满足收缩右边情况的判断语句*/) 	
				r = mid;
			else
				l = mid + 1;
		}	
				

说明:
跳出循环的条件永远为l=r,但此时分为两种情况:
情况一:没有找到想要的结果,根据具体问题另做处理(此时为边界情况或特殊输入情况)
情况二:找到了想要的结果,此时即为l(或arr[l]等)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值