Leecode热题100-41.缺失的第一个正数

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:

输入:nums = [1,2,0]
输出:3
解释:范围 [1,2] 中的数字都在数组中。

示例 2:

输入:nums = [3,4,-1,1]
输出:2
解释:1 在数组中,但 2 没有。

示例 3:

输入:nums = [7,8,9,11,12]
输出:1
解释:最小的正数 1 没有出现。

提示:

  • 1 <= nums.length <= 105
  • -231 <= nums[i] <= 231 - 1

解法都在代码注释里,看不懂的留言或者私信,看到第一时间解答

class Solution {
    /**假设我们的数是最理想的,一共有n个数,这n个数分别是1~n,分别放在0~n-1的位置上然后我们缺n+1,n+1就是第一个缺失的正数
    n就是我们有用的数的最大期望值
    但是我们遍历的过程中会发现一些比如是负数或者已经有过的有用的数或者大于n的数,那最大期望值就要-1了,因为现在已经有了一个没有用的值
    如果遇到位置不对的就交换到对的位置*/
    public int firstMissingPositive(int[] nums) {
        if(nums.length == 1) {
            return nums[0] == 1? 2 : 1;
        }
        /**定义最大期望值(最大的有用的值)*/
        int bestExpect = nums.length;
        /**已经确定的从1开始的连续区间的结尾*/
        int confirmedMax = 0;
        /**当前遍历的位置 */
        int cur = 0;
        /**bestExpect位置及以后都是无效的 */
        while(cur < bestExpect) {
            /**if条件的三段分别表示三种无效的数:1.小于等于已经确定的区间(包含小于0)2.大于最大期望值 3.它应该去的位置上的值和它一样  */
            if(nums[cur] == cur + 1) {
                /*如果在合适的位置扩大确定的区域 */
                cur ++;
                confirmedMax ++;
            } else if(nums[cur] <= confirmedMax || nums[cur] > bestExpect|| nums[nums[cur]-1] == nums[cur] ) {
                swap(nums, cur, --bestExpect);
            } else {
                /**有效但是不在自己该在的位置,回自己位置上去,这里cur不能++,因为它是换过来的应该继续考察 */
                swap(nums, cur, nums[cur] - 1);
            }
        }
        return confirmedMax + 1;
    }

    public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

修改后的代码如下: ```matlab % 设置参数 fs = 1000; % 采样率 bits = 12; % 分辨率 vref = 5; % 参考电压 % 生成数字信号 data = [-619.76715 -529.13434 -312.71863 -167.78337 -146.2360 -80.175125 -16.083157 -43.989765 -44.47398 -47.258278 -33.44726 -54.801384 -59.248947 -50.705193 -65.35704-57.36374 -45.225815 -31.582525 -28.156683 -59.727234 -54.488205 -24.398212 -43.865265 -45.365425 -77.97594 -54.436 -41.721855 -65.16225 -71.07881 -51.758736 -93.98244 -84.74326 -140.21878 -97.946014 -92.74178 -73.625725 -117.73671 -121.05837 -131.25688 -110.62707 -147.19264 -176.98892 -170.10733 -152.15996 -163.76915 -175.61983 -188.67313 -238.54276 -245.13528 -249.34978]; % 输入数据 data = data / 100; % 将输入数据除以100,得到一百分之一的幅值 t = 0:1/fs:(length(data)-1)/fs; % 时间向量 % 模拟DAC codebook = linspace(-vref, 0, 2^bits); % 生成量化码本 [dac_signal, quants] = quantiz(data, codebook(1:end-1), codebook); % 进行DAC模拟转换,输出DAC输出信号和量化误差 dac_signal = -dac_signal; % 反相输出信号,使其变为正数 analog_signal = vref*dac_signal; % 将DAC输出信号乘以参考电压得到模拟信号 % 输出结果 plot(t, analog_signal); % 绘制模拟信号波形 xlabel('Time (s)'); ylabel('Voltage (V)'); title('Analog Signal (scaled down by 100)'); ``` 这里直接将输入数据除以100,得到一百分之一的幅值,不需要对量化码本进行修改。输出的模拟信号电压就是输入数字信号的一百分之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值