LeetCode刷题笔记:41MissingPositive

问题描述


Given an unsorted integer array nums. Return the smallest positive integer that is not present in nums.

You must implement an algorithm that runs in O(n) time and uses O(1) auxiliary space.

Example 1:

Input: nums = [1,2,0]
Output: 3
Explanation: The numbers in the range [1,2] are all in the array.

Example 2:

Input: nums = [3,4,-1,1]
Output: 2
Explanation: 1 is in the array but 2 is missing.

Example 3:

Input: nums = [7,8,9,11,12]
Output: 1
Explanation: The smallest positive integer 1 is missing.

Constraints:

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

个人思路


第一遍自己思路

要求给一个未排序的整数数组,返回比这个数组中没出现的最小正整数X。基础数据结构是数组,数组的基础操作是排序和遍历。要求线性时间和就地排序,八大排序都不能用了,自然想到众数(169)那道题。但是 Boyer-Moore 是利用众数超出元素一半的办法来得到最多元素的。此题要求不涉及众数。我遍历一遍,找出大于0的最小值,如果不是1,那么X=1。如果是是1,那么之前遍历再加入求得最大值和最小值,判断他们的正负。最大值 = 1 ,自然就是2.最小值是1 ···G。双指针呢?一个指向正整数里最小的,一个指向次小的。但这俩连一起就不行了。

大佬思路

参考博客:https://leetcode.wang/leetCode-41-First-Missing-Positive.html

思路总结:对于这种要求空间复杂度的,我们可以先考虑如果有一个等大的空间,我们可以怎么做。然后再考虑如果直接用原数组怎么做,主要是要保证数组的信息不要丢失。目前遇到的,主要有两种方法就是交换和取相反数。

交换

类似于count sort的思路,但是是利用原数组作中间数组。从A[0] 开始,A[0]的元素大小 a 在数组长度内,就交换 A[0]A[x]。 接着处理交换过来的新A[0],<= 0 或者 超出数组长度 就不管,对A[1] 进行相同操作。这样操作结束之后。从 0 到 n 每个位置上都待着 有效范围外的数 或者 数组中包含的A[m] = m+1 这步排序最多进行 n 次,时间复杂度 O(n)。之后只需要再遍历数组找到第一个 A[k]!=k+1 的 k+1 就是答案。这一步也最坏是 O(n),那么总的时间复杂度是O(n),且满足就地排序

我的代码


 public static void firstMissingPositive(int[] nums) {
        for (int i = 0; i < nums.length ; i++) {
            //nums[nums[i]-1]!=nums[i] + for 可以保证重复的数字不会占用存在的数字 i 的 A[i]
            while (nums[i]!=i+1 && nums[i]>0 && nums[i]<=nums.length && nums[nums[i]-1]!=nums[i]){
                swap(nums,i,nums[i]-1);
            }
        }
        for (int i = 0; i < nums.length ; i++) {
            if (nums[i] != i+1) {
                System.out.println("Number is = " + (i+1));
                return;
            }
        }
        System.out.println("Number is = " + nums.length+1);
    }

    public static void swap(int[] nums,int a, int b) {
        int temp = nums[a];
        nums[a] = nums[b];
        nums[b] = temp;
    }
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值