leetcode
leetcode 2601 ~ 2650
点名

点名

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 44 ms, 内存: 15.8 MB


/*
 * 思路:
 * 使用IntStream和filter方法,找到第一个位置i,使得records[i] != i
 * 这个位置i即为缺失的学号
 */
import java.util.stream.IntStream;

public class Solution {
    public int findMissingNumber(int[] records) {
        return IntStream.range(0, records.length)
                         .filter(i -> records[i] != i)
                         .findFirst()
                         .orElse(records.length);
    }
}

解释

方法:

题解采用了二分查找的方法来寻找缺失的学号。由于数组是升序的,如果没有缺失,每个元素的值应该等于其索引。算法利用这一点,对数组进行二分查找。当中间元素的值等于其索引时,意味着缺失的学号在右侧,因此调整左边界;如果不等,说明缺失的学号在左侧或就是当前的中间位置,因此调整右边界。最终,左边界 'lo' 将停在缺失学号的位置。

时间复杂度:

O(log n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在nums[mid]等于mid时,可以确定缺失的学号在右侧?
当nums[mid]等于mid时,表示从索引0到mid的元素都恰好等于其索引值,说明这部分数组是完整的,没有缺失。因此,如果存在缺失的学号,它必须位于mid索引之后的数组部分。
🦆
在二分查找过程中,如果nums[mid]不等于mid,为何判定缺失的学号可能就是当前的mid位置?
如果nums[mid]不等于mid,说明在mid之前至少有一个数字是缺失的,因为理论上在没有缺失的情况下,每个元素应与其索引相等。这种不匹配可能是因为前面有缺失的数字导致后面的数字前移,所以缺失的学号可能就是mid本身或者在mid之前。
🦆
算法在最后返回lo的值作为缺失学号的依据是什么?
算法通过调整lo和hi的值来缩小搜索范围,最终lo将停在第一个使得nums[lo]不等于lo的位置,这个位置就是缺失数字的位置。如果数组是完整的,则lo会停在nums长度的位置,也就是最后一个数字的下一个位置。
🦆
如果数组中没有缺失的学号(即所有学号都齐全),这种算法是否会返回正确的结果?
是的,如果数组中没有缺失的学号,那么每个元素的索引都将与其值相等。在这种情况下,lo会逐步增加直到超过数组的最高索引,最后lo将等于nums的长度,也就是第一个不存在的索引,这也符合预期的结果。

相关问题