一. 简介
前面文章学习了对该题目的两种解题思路,文章如下:
力扣网C语言编程题:缺失的第一个正数-CSDN博客
但是前面的实现上在空间复杂度上没有满足要求。本文学习一种在空间复杂度上为 O(1)的思路。
二. 力扣网C语言编程题:缺失的第一个正数
题目:缺失的第一个正数
给你一个未排序的整数数组 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
解题思路三:
通过示例分析可知,缺失的一个最小正整数数的范围为 0 < data <= (n+1),这个分析结果很重要;
遍历数组元素,将每个元素交换放在对应位置上,例如,将元素值为1的元素 放在nums[0]上,2放在nums[1]上,...以此类推,numsSize值放在 nums[numsSize-1]位置上(假如有 元素值为numsSize)。
遍历数组,如果 num[i] != (i+1),则返回 (i+1)值,就是缺失的第一个正整数。如果在数组中找不到这样的元素,则缺失的第一个正整数就是 (numsSize+1);
C语言实现如下:
#include <stdio.h>int firstMissingPositive(int* nums, int numsSize) { if((nums == NULL) && (!numsSize)) {return -1;}int i = 0;//遍历数组,将元素放到对应的位置上for(i = 0; i < numsSize; i++) {//nums[i]位置上值不是 iwhile((nums[i] > 0) && (nums[i] <= numsSize) && (nums[i] != nums[nums[i]-1])) {int tmp = nums[i];nums[i] = nums[tmp-1];nums[tmp-1] = tmp;}}//遍历数组,找到第一个 nums[i] != i+1int data = 0; for(i = 0; i < numsSize; i++) {if(nums[i] != (i+1)) {data = (i+1);return data;}}//如果在数组没有找到 nums[i] != i+1,则最小正整数为(numsSize+1)data = numsSize+1; return data;
}
可以看出,这个实现方法实现了空间复杂度为 O(1)。不过时间复杂度增加了为 O(n*n);