【topic】:
Given an unordered integer array arr, find the smallest positive integer that does not appear in the array.
E.g:
arr=[-1,2,3,4]. Returns 1.
arr=[1,2,3,4]. Returns 5.
The time complexity is required to be O(N) and the space complexity is O(1).
【解答】:https://www.cnblogs.com/xiaomoxian/p/5189810.html
- Generate two variables before iterating over arr. The variable l indicates that the range of positive integers that the array arr has contained so far is [1,l], so l=0 before it starts, indicating that arr does not contain any positive integers. The variable r represents the traversal so far. In the case of the subsequent optimal situation, the range of positive integers that arr may contain is [1, r], so before it starts, let r=N, and r also represents the current end of arr Location.
- Traverse arr from left to right, and traverse to position l, where the number of position l is arr[l].
- If arr[l]=l+1, l++. Repeat step 2.
- If arr[l]<=l, before traversing arr[l], the range of positive integers that arr may contain in the subsequent optimal case is [1,r], and the range of positive integers already contained is [1,l] , so the numbers on [1+l,r] are needed. The number in the range of [l+1,r] is one less, and the range of positive integers that may be included is reduced to [1,r-1]. At this time, the number in the last position (arr[r-1]) is placed in At position l, the next step is to check this number, then r--. Repeat step 2.
- If arr[l]>r, the same as step 4.
- If arr[arr[l]-1]==arr[l], it means that step 4 and step 5 are not hit, arr[l] is a number in the range of [l+1,r], and this number should be in arr[l]-1 position. However, at this time, it is found that the number at the position of arr[l]-1 is already arr[l], indicating that there are two arr[l]. Since there are duplicate values in [l+1,r], then [l+ The number in the range of 1,r] is one less, the same as the processing method of step 4 and step 5.
- If none of steps 4/5/6 are hit, it means that a number in the range [l+1,r] has been found, and no duplication has been found at this time. Then arr[l] should be placed in the arr[l]-1 position.
- In the end, the l position and the r position will be the same. The range of positive integers that arr already contains is [1,l], and you can return l+1.
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0;i < n;i ++){
arr[i] = sc.nextInt();
}
int res = findMin(arr);
System.out.print(res);
sc.close();
}
public static int findMin(int[] arr){
int len = arr.length;
int l = 0;
int r = len;
while (l < r){
if (arr[l] == l + 1){//如果数字按顺序出现在正确的位置
l ++;
}else if (arr[l] <= l || arr[l] > r || arr[l] == arr[arr[l] - 1]){//out of range of unchecked numbers or duplicates
arr[l] = arr[-- r];
}else {//The array is not in the correct position, put it in the correct position
swap(arr,l,arr[l] - 1);
}
}
return l + 1;
}
public static void swap(int[] arr,int i,int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}