您的位置:首页 > 其它

[LeetCode-268] Missing Number(找缺失的数字)

2015-10-12 17:04 459 查看
Given an array containing n distinct numbers taken from 
0, 1, 2, ..., n
,
find the one that is missing from the array.

For example,

Given nums = 
[0, 1, 3]
 return 
2
.

Note:

Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

1、无序数组

【问题描述】输入的数组是一个无序数组(当缺失添加进输入时,排序后是一个等差数列,公差为1),找到缺失数,题目要求时间复杂度为n,所以想先将数组排序的想法肯定不实际,由题意,大小为n的数组里的所有数都是0
- n之间的数,无需数组,我们首先遍历一遍记录最大、最小值以及实际数组和,用最小值到最大值相加之后得到的期望数组和减去实际数组和,就是缺失的整数。

题目中有几个比较恶心的处理

当数组长度为1,数组元素为0,此时默认缺失数为1;
当数组长度为1时,数组元素不为0,此时应该返回0,说明输入内容无效

其中程序有个易错点,当期望数组和减去实际数组和可能等于0,此时存在两种情况①缺失数为0②数组第一个元素为0,缺失数为最大值+1;
代码如下:
int missingNumber(int* nums, int numsSize)
{
/*1.Exception handling*/
if(!nums||numsSize<=0) {
return 0;
}
/*Such as 1,should return 0*/
if(nums[0]!=0&&numsSize==1) {
return 0;
}
int i = 0;
int MAXNUM = 0xffffffff;
int MINNUM = 0x7fffffff;
long long numsAddSum = 0;/*long long is to advoid overflow*/
long long numsAddSumReal = 0;
int nResult = 0;

for(i = 0;i<numsSize;i++) {
if(nums[i]>MAXNUM) {
MAXNUM = nums[i];
}
if(nums[i]<MINNUM) {
MINNUM = nums[i];
}
numsAddSum += nums[i];
}
i = MINNUM;
while(i<=MAXNUM) {
numsAddSumReal +=i;
i++;
}
nResult = (int)numsAddSumReal-numsAddSumReal;

/*Expect numsAddSumReal - numsAddSumReal = 0*/
if(nResult==0&&MINNUM==0){
return (MAXNUM+1);
}
else if(nResult==0&&MINNUM!=0) {
return 0;
}

return nResult;
}

2、有序数组

【问题描述】输入的数组是一个有序数组,找到缺失数,题目要求时间复杂度为n,由题意,大小为n的数组里的所有数都是0
- n之间的数,作为等差数列,最大值和最小值一眼就可以看出,可以对上述方法直接进行改进;
/*有序数组*/
int missingNumber(int* nums, int numsSize)
{
/*1.Exception handling*/
if(!nums||numsSize<=0) {
return 0;
}
/*Such as 1,should return 0*/
if(nums[0]!=0&&numsSize==1) {
return 0;
}

int i = 0;
int MAXNUM = nums[numsSize-1];
int MINNUM = nums[0];

long long numsAddSumExpect = 0;/*long long is to advoid overflow*/
long long numsAddSumReal = 0;
int nResult = 0;

for(i = 0;i<numsSize;i++) {
numsAddSumReal += nums[i];
}
i = MINNUM;
while(i<=MAXNUM) {
numsAddSumExpect +=i;
i++;
}

nResult = (int)numsAddSumExpect-numsAddSumReal;

/*Expect numsAddSumReal - numsAddSumReal = 0*/
if(nResult==0&&MINNUM==0){
return (MAXNUM+1);
}
else if(nResult==0&&MINNUM!=0) {
return 0;
}

return nResult;

}

3、二分搜索法改进代码

中点的下标和中点的值相同时,说明从起始到中点没有错位,缺失数应该在数组后边。如果不相等,说明前面已经有错位,缺失数在左边。如果缺失数是最后一个的话,那整个数组都没有错位,则要返回最后一个加1。
注意:中点的值需要和中点值+起始值(偏移)。

/*二分搜索法,找缺失数*/
int missingNumber(int* nums, int numsSize)
{
/*1.Exception handling*/
if(!nums||numsSize<=0) {
return 0;
}
/*Such as 1,should return 0*/
if(nums[0]!=0&&numsSize==1) {
return 0;
}
else if(nums[0]==0&&numsSize==1) {
return (0+1);
}

int min = 0;
int max = numsSize-1;
while(min<=max) {
int mid = min+(max-min)/2;
if((mid+nums[0])==nums[mid]) {
min = mid+1;
}
else {
max = mid-1;
}
}
/*没有发生错位*/
if(min == nums[min]&&nums[0]==0) {
return (nums[numsSize-1]+1);
}
else if(min == nums[min]&&nums[0]!=0) {
return 0;
}

return (min+nums[0]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息