1、题目描述
某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records
。假定仅有一位同学缺席,请返回他的学号。
2、算法思路
一、求和公式
使用高中学过的求和公式 ((首项+尾项)*项数)/2 和 数组中的值比较 缺少的那个就是返回的学号
比如 [0,1,2,3,5 ] 应该是 (0+5)*6/2 因为正常是[0,1,2,3,4,5] 0是首项,5是尾项,有6个数就是项数
比如[0,1,2,3,4] 应该是 (0+5)*6/2 因为只有一个人缺少所以尾项是5,正常也是0-6
求和公式 - 数组中的总和就是得出结果
二、二分法
因为是升序,可以是用二分法。我们可以发现正常的下标对应数组中的数是一样的,所以我们可以
当mid等于records.[mid]的时候 是mid的左边没有问题,所以是右边的缺少
当mid不等于records.[mid]的时候 是mid的左边有问题,所以是左边缺少
3、算法代码
一、求和公式代码
class Solution {
public static int takeAttendance(int[] records){
int right = records.length;
int sums = ((0+right)*(records.length+1))/2;
int recordNums = Arrays.stream(records).sum();
return sums-recordNums;
}
}
二、二分法代码
class Solution {
public static int takeAttendance(int[] records) {
if (records.length==1 && records[0]==1) return 0;
int left = 0,right = records.length-1;
while (left < right){
int mid = (left + right) >>>1;
if (mid == records[mid]) left = mid +1;
else right = mid;
}
return left == records[left] ? left+1:left;
}
}