1)题目:给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4
2)思路与代码:
源码中使用到的ArrrayList,是调用的是自己实现的ArrayList,自己实现的ArrayList源码地址:https://blog.csdn.net/u012441545/article/details/89667486
package com.sam.datastruct.arrayList;
import java.util.HashSet;
import java.util.Set;
public class P2_13 {
/*
* 思路:使用Java set自带的contains方法查看数值是否存在
* 时间复杂度O(nlogn)
* 空间复杂度O(1)*/
public Integer function(int[] s){
Set<Integer> exist = new HashSet<>();
for (int i : s) {
if (i > 0) {
exist.add(i);
}
}
for (int i = 1; i <= Integer.MAX_VALUE; ++i) {
if (!exist.contains(i)) {
return i;
}
}
return -1;
}
/*
* 思路:使用位图记录数据是否存在的信息,因为每个int有32个bit,故可以记录32个数据的存在情况
* 时间复杂度O(n)
* 空间复杂度O(1)*/
public Integer function1(int[] s){
int[] exist = new int[Integer.MAX_VALUE/32];
for (int i : s) {
if (i > 0) {
exist[i/32] |= 1<<i%32; //数据i的信息记录在exist数组的第i/32个数据的第i%32位上 |= 表示左边与右边做或运算并将结果赋予左边,1<<n表示1左移n位,即乘以2^n
}
}
for (int i = 1; i <= Integer.MAX_VALUE; ++i) {
if ((exist[i/32] & (1<<i%32)) == 0) {
return i;
}
}
return -1;
}
/*
* 思路:使用数组记录1到最大值间数据是否出现,之后遍历找出未出现的第一个数据,如果没有则返回最大值+1
* 时间复杂度O(n)
* 空间复杂度O(1)*/
public int function2(int[] s){
int maxValue = s[0];
for (int i : s) {
if (i > maxValue) {
maxValue = i;
}
}
int[] exist = new int[maxValue + 1];
for (int i : s){
if (i > 0) {
exist[i] = 1;
}
}
for (int i = 1; i <= maxValue; ++i){
if (exist[i] == 0) {
return i;
}
}
return maxValue + 1;
}
public static void main(String[] args) {
P2_13 p = new P2_13();
int size = 100;
int[] s = new int[]{0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,50,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,50,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,50,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5,0,5,5,3,5,7,5,5,0,0,0,5,5,6,4,5,5,5,4,5,4,2,5,4,5,5,2,1,6,5,5,7,5};
/*Random random = new Random();
for(int i = 0; i < size; ++ i){
s[i] = 1 + random.nextInt(2);
}*/
for(int integer : s){
System.out.print(integer + ", ");
}
System.out.println();
long t1 = System.nanoTime();
System.out.println(p.function(s));
System.out.println(System.nanoTime() - t1);
t1 = System.nanoTime();
System.out.println(p.function1(s));
System.out.println(System.nanoTime() - t1);
t1 = System.nanoTime();
System.out.println(p.function2(s));
System.out.println(System.nanoTime() - t1);
}
}