First Missing Positive 找第一个没在array中出现的正数@LeetCode

本文探讨了如何在未排序的整数数组中找到首个缺失的正整数,提出了一种利用数组下标作为哈希值的方法,通过交换元素到其应该在的位置,最后遍历数组找出首个错位元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题可能会有歧义,意思是要找出第一个没在array中出现的正数!

核心思想是利用数组下标来作为hash值,通过swap把元素移到应该在的位置,然后遍历数组,找到第一个错位的元素。


主要参考了:

http://n00tc0d3r.blogspot.com/2013/03/find-first-missing-positive.html

http://www.cnblogs.com/AnnieKim/archive/2013/04/21/3034631.html


这两个思路,尤其是第一个。

A few quick thoughts:
  • Sort all numbers and iterate through to find the first missing integer? No, most sorting algorithms take time at least O(nlogn).
  • How about linear sorting algorithm? No, bucket sort requires O(n) space.
  • Mapping all positive integers to a hash table and iterate from 1 to the length of the array to find out the first missing one? No, hash table requires O(n) space.

Then, how to solve this?

Let's take another look at the problem. It is asking for the first missing POSITIVE integer.
So, given a number in the array,
  • if it is non-positive, ignore it;
  • if it is positive, say we have A[i] = x, we know it should be in slot A[x-1]! That is to say, we can swap A[x-1] with A[i] so as to place x into the right place.
We need to keep swapping until all numbers are either non-positive or in the right places. The result array could be something like [1, 2, 3, 0, 5, 6, ...]. Then it's easy to tell that the first missing one is 4 by iterate through the array and compare each value with their index.



package Level5;

import java.util.Arrays;


/**
 * First Missing Positive
 * 
 * Given an unsorted integer array, find the first missing positive integer.

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.
 */
public class S41 {

	public static void main(String[] args) {
		int[] A = {1,1};
		System.out.println(firstMissingPositive(A));
	}
	
	public static void swap(int[] A, int a, int b){
		int tmp = A[a];
		A[a] = A[b];
		A[b] = tmp;
	}
	
	public static int firstMissingPositive(int[] A) {
		int i = 0;
        while(i<A.length){
        	// swap的条件是要在数组范围内,且要交换的值没有在正确位置,否则就没必要交换了;而且交换值与被交换值不能相同,否则会死循环
        	if(A[i]>0 && A[i]-1<A.length && A[i]!=i+1 && A[i]!=A[A[i]-1]){
        		swap(A, i, A[i]-1);
        	}else{
        		i++;
        	}
        }
        
//        System.out.println(Arrays.toString(A));
        for(i=0; i<A.length; i++){	// 从头开始遍历,找到第一个不在应在位置上的元素
        	if(A[i] != i+1){
        		return i+1;
        	}
        }
        
        return A.length+1;		// 说明所有元素都在正确的位置,那么只能返回数组长度后的第一个元素了
    }

}



public class Solution {
    public int firstMissingPositive(int[] A) {
        if(A.length == 0) {
            return 1;
        }
        int i = 0;
        while(i < A.length) {
            if(A[i] > 0 && A[i] <= A.length && i != A[i]-1 && A[i] != A[A[i]-1]) {
                swap(A, i, A[i]-1);
            } else {
                i++;
            }
        }
        
        i = 0;
        for(i=0; i<A.length; i++) {
            if(i != A[i]-1) {
                return i+1;     // map from 0 based index to 1 based
            }
        }
        
        return A.length+1;
    }
    
    public void swap(int[] A, int i, int j) {
        int tmp = A[i];
        A[i] = A[j];
        A[j] = tmp;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值