题中信息:
- 递增排序
- n-1长度的数组内有n-1个数字,范围是0~n-1,即只缺失一个数字。
1. 遍历
最简单的方法就是从前到后遍历数组,直到找到第一个数组下标和当前元素不等的数据,此时的下标值即为缺失的数字。
- 有对应关系:
{ 在 缺 失 的 数 字 前 : 数 组 下 标 = = 当 前 元 素 在 缺 失 的 数 字 后 : 数 组 下 标 + 1 = = 当 前 元 素 \begin{cases} 在缺失的数字前:数组下标==当前元素& \\ 在缺失的数字后:数组下标+1==当前元素&\\ \end{cases} {在缺失的数字前:数组下标==当前元素在缺失的数字后:数组下标+1==当前元素
但要注意的是,缺失的数字恰好是n-1时的情况,此时遍历整个数组每个元素的下标和元素都相等。 - 平均时间复杂度O(n),空间复杂度O(1)。
public int missingNumber(int[] nums) {
if(nums.length>=1) {
int length = nums.length;
int i;
for(i=0;i<length;i++) {
if(nums[i]==i) continue;
else break;
}
return i;
}
return -1;
}
2. 二分查找
涉及递增排序的数组通常用二分查找法解决。
{
m
i
d
d
l
e
=
=
n
u
m
s
[
m
i
d
d
l
e
]
缺
失
的
数
字
在
m
i
d
d
l
e
的
右
方
m
i
d
d
l
e
<
n
u
m
s
[
m
i
d
d
l
e
]
缺
失
的
数
字
在
m
i
d
d
l
e
的
左
方
\begin{cases} middle==nums[middle]&{缺失的数字在middle的右方}\\ \\ middle<nums[middle]&{缺失的数字在middle的左方}\\ \end{cases}
⎩⎪⎨⎪⎧middle==nums[middle]middle<nums[middle]缺失的数字在middle的右方缺失的数字在middle的左方
- 不可能存在
middle>nums[middle]
的情况。 - 时间复杂度O(logN),空间复杂度O(1)。
public int missingNumber(int[] nums) {
int length = nums.length;
int left = 0, right = length-1, mid;
while(left<=right) {
mid = (left+right)/2;
if(nums[mid]==mid) {
left = mid+1;
}
else right=mid-1;
}
return left;
}
ps.这居然是我第一次通过除了遍历法之外的方法编程、调试成功且代码和大家的都差不多简洁做出来的题!暴风哭泣…希望尽快从菜的路上走出去!