自己的理解:
暴力解决法是遍历一遍数组
找不到题目的二段性 ?
写上下标之后 立马就看到了二段性
位运算 //知识补充:
相同的数异或为0 a^a = 0 任何数与0异或为本身 a^0 = a
我们分别异或 01234完整序列和0134实际序列 0 ^ 1 ^ 2 ^ 3 ^ 4 0 ^ 1 ^ 3 ^ 4
由于异或的交换律,相同的数字会抵消: (0^0) ^ (1^1) ^ 2 ^ (3^3) ^ (4^4) = 0 ^ 0 ^ 2 ^ 0 ^ 0 = 2
细节:
第一种解法里面对于特殊情况2 如何写代码 特殊情况1要考虑到以及如何写代码
高斯求和里面对于特殊情况的考虑
别人的讲解:
解法1:哈希表 (n个数)创建n+1大小的哈希表 遍历原始数组把元素往哈希表里填 哪个位置没有填到 那个位置就是我们要找到
//这里的哈希表可以自己模拟一个
解法2:直接遍历找结果
解法3:位运算 相同的数会抵消 缺少的数因为没有数与它抵消
解法4:高斯求和公式 哈哈还能这么整我嘞个豆 求和公式:(首项+末项)X 项数 /2
解法5:二分算法

下面是题目、效果图和代码:


java
class Solution
{
public int takeAttendance(int[] records)
{
int ret = 0;
//特殊情况1:如果第一个数字不是0 缺失的就是0
if(records[0] != 0) return 0;
for(int i= 0;i<records.length-1;i++)
{
if(records[i+1]-records[i]==2)
{
ret = i+1;
return ret;
}
}
//特殊情况2:如果中间没有缺失 缺失的就是最后一个数字
return records[records.length-1]+1;
}
}

java
//哈希表 解法
class Solution
{
public int takeAttendance(int[] records)
{
int n = records.length;
boolean[] hash = new boolean[n+1];//定义一个boolean类型的数组
//将哈希表里面填充好元素
for(int num: records)
{
hash[num] = true;
}
//找到第一个为false的位置
for(int i = 0; i<=n ; i++)
{
if(! hash[i] )
{
return i ;
}
}
return -1;
}
}

java
//位运算 解法
class Solution
{
public int takeAttendance(int[] records)
{
int n = records.length;
int result = 0;
//第一步 异或所有应该存在的数字(0到n)
for(int i = 0 ; i<=n ;i++)
{
result ^= i ; //相当于result= result^i;
}
//第二步 异或实际存在的数字
for(int num: records)
{
result ^= num;//相同的数字会抵消 不同的数字会留下来0
}
return result;
}
}

java
//等差数列高斯求和 解法
class Solution
{
public int takeAttendance(int[] records)
{
if(records[0] != 0) return 0;
if(records.length == 1 && records[0] == 0) return 1;
//先按照原先那样得到一个和 然后减去数组的和
int total = 0;
for(int num:records) total += num ;
int num = records[records.length-1];
int total02 = 0;
for(int i = 0;i<=num;i++) total02 += i;
if(total02-total==0) return records[records.length-1]+1;
return total02-total;
}
}
//细节问题是 如果是空数组 或者缺少第一个学号的情况(缺少0)
//各种细节问题要注意 这个解法最麻烦了 思路麻烦 代码也麻烦

java
//二分查找解法
class Solution
{
public int takeAttendance(int[] records)
{
int left = 0,right = records.length-1;
if(records[0] != 0) return 0;
while(left<right)
{
int mid = left + (right-left)/2;
if(records[mid]==mid) left = mid+1;
else right=mid;
}
//处理细节问题
return records[left]==left ? left + 1 : left;
}
}
//xiyu251104&1#3*8