java实现第一个缺失的正整数_Day24 缺失的第一个正数

这篇博客探讨了如何在未排序的整数数组中找到第一个缺失的正整数,提出了三种不同的Java解决方案,包括时间复杂度为O(n)且仅使用常数级别额外空间的方法。通过将数据按序处理、使用哈希表标记和数据归位等策略,实现了高效查找。博客还分析了各种方法的时间和空间复杂度。
摘要由CSDN通过智能技术生成

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

进阶:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?

示例1:

输入:nums = [1,2,0]

输出:3

示例2:

输入:nums = [3,4,-1,1]

输出:2

示例3:

输入:nums = [7,8,9,11,12]

输出:1

提示:

0 <= nums.length <= 300

-231 <= nums[i] <= 231 - 1

Java解法

思路:

找没有出现的最小值+未排序--> 将数据按序

新建对应数组,下标位置存储对应数据存储index出现个数

为0表示该数据没有出现,抛出,全都出现,表示长度值

存储用了nums长度(不知道是否符合进阶要求,查看下官方解)

package sj.shimmer.algorithm.ten_3;

/**

* Created by SJ on 2021/2/17.

*/

class D24 {

public static void main(String[] args) {

System.out.println(firstMissingPositive(new int[]{1,2,0}));

System.out.println(firstMissingPositive(new int[]{3,4,-1,1}));

System.out.println(firstMissingPositive(new int[]{7,8,9,11,12}));

System.out.println(firstMissingPositive(new int[]{1}));

}

public static int firstMissingPositive(int[] nums) {

if (nums == null||nums.length==0) {

return 1;

}

int[] n = new int[nums.length];

for (int i = 0; i < nums.length; i++) {

int num = nums[i]-1;//-1表示位置进行前移一位,0不为正数

if (num>nums.length-1||num<0) {

continue;

}

n[num] = ++n[num];

}

for (int i = 0; i < n.length; i++) {

if (n[i]==0) {

return i+1;

}

}

return n.length+1;

}

}

039af9e4f03e

image

官方解

角度算法都可以,但效率都没有特别好。。。

哈希表

原文可以进链接,这里表述下我的理解

将所有负数置为长度+1(范围外),将所有数据变为正数

对所有在范围内的数据打上标记(将该数据的值减一的下标值进行添加-号,不用重复加)

遍历数据的时候发现有负数说明下一个数据是经历过标记的

相比较而言,内存上减少了一般,但依然是常数级的,两个循环可以优化为一个,个人之前考虑过在同一数组上处理,但没找到合适的标记方式,官方解这个角度NICE

class Solution {

public int firstMissingPositive(int[] nums) {

int n = nums.length;

for (int i = 0; i < n; ++i) {

if (nums[i] <= 0) {

nums[i] = n + 1;

}

}

for (int i = 0; i < n; ++i) {

int num = Math.abs(nums[i]);

if (num <= n) {

nums[num - 1] = -Math.abs(nums[num - 1]);

}

}

for (int i = 0; i < n; ++i) {

if (nums[i] > 0) {

return i + 1;

}

}

return n + 1;

}

}

039af9e4f03e

image

时间复杂度:O(N)

空间复杂度:O(1)

置换

这个应该是我想到但没做到的想法(主要是想一次循环完成),将数据归位

[3, 4, -1, 1] 恢复为:[1, -1, 3, 4]

官方解是每次循环交换一个正确的数据

class Solution {

public int firstMissingPositive(int[] nums) {

int n = nums.length;

for (int i = 0; i < n; ++i) {

while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {

int temp = nums[nums[i] - 1];

nums[nums[i] - 1] = nums[i];

nums[i] = temp;

}

}

for (int i = 0; i < n; ++i) {

if (nums[i] != i + 1) {

return i + 1;

}

}

return n + 1;

}

}

039af9e4f03e

image

时间复杂度:O(N)

空间复杂度:O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值