Algorithm 缺少整数变量-需要O(n)解决方案
问题来自Codibility编程培训,听起来如下: 我们有一个数组(A[]),其中有n个元素(范围从1到100000),这些是我们的参数。数组的元素是来自的整数−2147483648到2147483647,我们需要找到数组中不存在的最小正整数。当然,这可以在O(n*logn)中轻松完成,方法是将它们全部排序并遍历已排序的数组,查找缺少的posiitve编号(最后一个操作在我的解决方案中具有O(n)最差的时间复杂度)。但根据Codibility的说法,整个问题可以在O(n)中完成,我看不到任何方法可以做到这一点。有人能给我一些建议让我摆脱困境吗Algorithm 缺少整数变量-需要O(n)解决方案,algorithm,Algorithm,问题来自Codibility编程培训,听起来如下: 我们有一个数组(A[]),其中有n个元素(范围从1到100000),这些是我们的参数。数组的元素是来自的整数−2147483648到2147483647,我们需要找到数组中不存在的最小正整数。当然,这可以在O(n*logn)中轻松完成,方法是将它们全部排序并遍历已排序的数组,查找缺少的posiitve编号(最后一个操作在我的解决方案中具有O(n)最差的时间复杂度)。但根据Codibility的说法,整个问题可以在O(n)中完成,我看不到任何方法
PS这里有一个链接,指向不允许复制的问题的详细描述-构建一个包含所有值的哈希表。对于数字1到n+1,检查它们是否在哈希表中。至少有一个不是。打印出最低的数字
这是O(n)的预期时间(你可以得到)。请参阅@Gassa的答案,了解如何避免哈希表而选择大小为O(n)的查找表。根据鸽子洞原理,数组中至少有一个数字1、2、…、n+1不在数组中。 让我们创建一个大小为n+1的布尔数组
b
,以存储这些数字是否都存在
现在,我们处理输入数组。如果我们找到一个从1到n+1的数字,我们会在b
中标记相应的条目。如果我们看到的数字不符合这些界限,只需丢弃它并继续下一个。两种情况下,每个输入条目都是O(1),总的O(n)
处理完输入后,我们可以在布尔数组b
中找到第一个未标记的条目,通常在O(n)中。静态int-spn(int[]数组)
{
int返回值=1;
int currentCandidate=2147483647;
foreach(数组中的int项)
{
如果(项目>0)
{
如果(项目<当前候选项目)
{
当前候选人=项目;
}
如果(项我认为解决方案比使用n(100000)个元素的布尔数组“标记”相应值更复杂。大小为n的布尔数组不会“直接”映射到可能的值范围(−2147483648至2147483647)。
我编写的这个Java示例试图通过基于与最大值的偏移量映射值来映射100K行。它还执行一个模数,以将生成的数组减小到与样本元素长度相同的大小
/**
*
* This algorithm calculates the values from the min value and mods this offset with the size of the 100K sample size.
* This routine performs 3 scans.
* 1. Find the min/max
* 2. Record the offsets for the positive integers
* 3. Scan the offsets to find missing value.
*
* @author Paul Goddard
*
*/
public class SmallestPositiveIntMissing {
static int ARRAY_SIZE = 100000;
public static int solve(int[] array) {
int answer = -1;
Maxmin maxmin = getMaxmin(array);
int range = maxmin.max - maxmin.min;
System.out.println("min: " + maxmin.min);
System.out.println("max: " + maxmin.max);
System.out.println("range: " + range);
Integer[] values = new Integer[ARRAY_SIZE];
if (range == ARRAY_SIZE) {
System.out.println("No gaps");
return maxmin.max + 1;
}
for (int val: array) {
if (val > 0) {
int offset = val - maxmin.min;
int index = offset % ARRAY_SIZE;
values[index] = val;
}
}
for (int i = 0; i < ARRAY_SIZE; i++) {
if (values[i] == null) {
int missing = maxmin.min + i;
System.out.println("Missing: " + missing);
answer = missing;
break;
}
}
return answer;
}
public static Maxmin getMaxmin(int[] array) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int val:array) {
if (val >=0) {
if (val > max) max = val;
if (val < min) min = val;
}
}
return new Maxmin(max,min);
}
public static void main(String[] args) {
int[] A = arrayBuilder();
System.out.println("Min not in array: " + solve(A));
}
public static int[] arrayBuilder() {
int[] array = new int[ARRAY_SIZE];
Random random = new Random();
System.out.println("array: ");
for (int i=0;i < ARRAY_SIZE; i++) {
array[i] = random.nextInt();
System.out.print(array[i] + ", ");
}
System.out.println(" array done.");
return array;
}
}
class Maxmin {
int max;
int min;
Maxmin(int max, int min) {
this.max = max;
this.min = min;
}
}
/**
*
*此算法根据最小值计算值,并使用100K样本大小修改此偏移量。
*此例程执行3次扫描。
*1.找到最小/最大值
*2.记录正整数的偏移量
*3.扫描偏移以查找缺少的值。
*
*@作者保罗·戈达德
*
*/
公共类SmallestPositiveIntMissing{
静态整数数组_SIZE=100000;
公共静态int solve(int[]数组){
int-answer=-1;
Maxmin-Maxmin=getMaxmin(数组);
int range=maxmin.max-maxmin.min;
System.out.println(“min:+maxmin.min”);
System.out.println(“max:+maxmin.max”);
System.out.println(“范围:“+范围”);
整数[]值=新整数[数组大小];
if(范围==数组大小){
System.out.println(“无间隙”);
返回maxmin.max+1;
}
for(int val:array){
如果(val>0){
int offset=val-maxmin.min;
int index=偏移量%ARRAY\u SIZE;
值[索引]=val;
}
}
for(int i=0;i=0){
如果(val>max)max=val;
如果(val
可能会有帮助,我正在使用算术级数来计算和,并使用二进制searach提取元素。使用几百个值的数组进行检查效果良好。因为在步骤2中有一个for循环和I会话,O(n/2)或更小
def missingement(A):
B=[x代表范围(1,最大值(A)+1,1)内的x]
n1=len(B)-1
开始=0
end=(n1)//2
结果=0
印刷品(A)
印刷品(B)
如果(len(A)BinSum(B,开始,结束):
结束=(结束+开始)//2
如果(结束-开始)=len(C):
结束=透镜(C)-1
总和=n*((C[开始]+C[结束])/2)
回报金额
def main():
A=[1,2,3,5,6,7,9,10,11,12,14,15]
打印(“缺少的最小数字为”,缺少元素(A))
如果uuuu name_uuuuuu=='uuuuuu main:main()
它对我很有效。它不是O(n),但简单一点:
import java.util.stream.*;
class Solution {
public int solution(int[] A) {
A = IntStream.of(A)
.filter(x->x>0)
.distinct()
.sorted()
.toArray();
int min = 1;
for(int val : A)
{
if(val==min)
min++;
else
return min;
}
return min;
}
}
今天写了这篇文章,得到了100/100。这不是最优雅的解决方案,但很简单
def Missingelement (A):
B = [x for x in range(1,max(A)+1,1)]
n1 = len(B) - 1
begin = 0
end = (n1)//2
result = 0
print(A)
print(B)
if (len(A) < len(B)):
for i in range(2,n1,2):
if BinSum(A,begin,end) > BinSum(B,begin,end) :
end = (end + begin)//2
if (end - begin) <= 1 :
result=B[begin + 1 ]
elif BinSum(A,begin,end) == BinSum(B,begin,end):
r = end - begin
begin = end
end = (end + r)
if begin == end :
result=B[begin + 1 ]
return result
def BinSum(C,begin,end):
n = (end - begin)
if end >= len(C):
end = len(C) - 1
sum = n*((C[begin]+C[end])/2)
return sum
def main():
A=[1,2,3,5,6,7,9,10,11,12,14,15]
print ("smallest number missing is ",Missingelement(A))
if __name__ == '__main__': main()
import java.util.stream.*;
class Solution {
public int solution(int[] A) {
A = IntStream.of(A)
.filter(x->x>0)
.distinct()
.sorted()
.toArray();
int min = 1;
for(int val : A)
{
if(val==min)
min++;
else
return min;
}
return min;
}
}
public int solution(int[] A) {
int max = A.length;
int threshold = 1;
boolean[] bitmap = new boolean[max + 1];
//populate bitmap and also find highest positive int in input list.
for (int i = 0; i < A.length; i++) {
if (A[i] > 0 && A[i] <= max) {
bitmap[A[i]] = true;
}
if (A[i] > threshold) {
threshold = A[i];
}
}
//find the first positive number in bitmap that is false.
for (int i = 1; i < bitmap.length; i++) {
if (!bitmap[i]) {
return i;
}
}
//this is to handle the case when input array is not missing any element.
return (threshold+1);
}
int solution(int A[], int N) {
// write your code in C99
long long sum=0;
long long i;
long long Nsum=0;
for(i=0;i<N;i++){
sum=sum + (long long)A[i];
}
if (N%2==0){
Nsum= (N+1)*((N+2)/2);
return (int)(Nsum-sum);
}
else{
Nsum= ((N+1)/2)*(N+2);
return (int)(Nsum-sum);
}
}
class Solution {
public int solution(int[] A) {
int x = 0;
while (x < A.length) {
// Keep swapping the values into the matching array positions.
if (A[x] > 0 && A[x] <= A.length && A[A[x]-1] != A[x]) {
swap(A, x, A[x] - 1);
} else {
x++; // Just need to increment when current element and position match.
}
}
for (int y=0; y < A.length; y++) {
// Find first element that doesn't match position.
// Array is 0 based while numbers are 1 based.
if (A[y] != y + 1) {
return y + 1;
}
}
return A.length + 1;
}
private void swap (int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
public int solutionMissingInteger(int[] A) {
int solution = 1;
HashSet<Integer> hashSet = new HashSet<>();
for(int i=0; i<A.length; ++i){
if(A[i]<1) continue;
if(hashSet.add(A[i])){
//this int was not handled before
while(hashSet.contains(solution)){
solution++;
}
}
}
return solution;
}
function solution($A){
$A = array_unique($A);
sort($A);
if (empty($A)) return 1;
if (max($A) <= 0) return 1;
if (max($A) == 1) return 2;
if (in_array(1, $A)) {
$A = array_slice($A, array_search(1, $A)); // from 0 to the end
array_unshift($A, 0); // Explanation 6a
if ( max($A) == array_search(max($A), $A)) return max($A) + 1; // Explanation 6b
for ($i = 1; $i <= count($A); $i++){
if ($A[$i] != $i) return $i; // Explanation 6c
}
} else {
return 1;
}
}
def solution(A):
"""
Sort the array then loop till the value is higher than expected
"""
missing = 1
for elem in sorted(A):
if elem == missing:
missing += 1
if elem > missing:
break
return missing
int[] copy = new int[A.length];
for (int i : A)
{
if (i > 0 && i <= A.length)
{
copy[i - 1] = 1;
}
}
for (int i = 0; i < copy.length; i++)
{
if (copy[i] == 0)
{
return i + 1;
}
}
return A.length + 1;
public static int solution(int[] A)
{
var lookUpArray = new bool[A.Length];
for (int i = 0; i < A.Length; i++)
if (A[i] > 0 && A[i] <= A.Length)
lookUpArray[A[i] - 1] = true;
for (int i = 0; i < lookUpArray.Length; i++)
if (!lookUpArray[i])
return i + 1;
return A.Length + 1;
}
int compare( const void * arg1, const void * arg2 )
{
return *((int*)arg1) - *((int*)arg2);
}
solution( int A[], int N )
{
// Make a copy of the original array
// So as not to disrupt it's contents.
int * A2 = (int*)malloc( sizeof(int) * N );
memcpy( A2, A1, sizeof(int) * N );
// Quick sort it.
qsort( &A2[0], N, sizeof(int), compare );
// Start out with a minimum of 1 (lowest positive number)
int min = 1;
int i = 0;
// Skip past any negative or 0 numbers.
while( (A2[i] < 0) && (i < N )
{
i++;
}
// A variable to tell if we found the current minimum
int found;
while( i < N )
{
// We have not yet found the current minimum
found = 0;
while( (A2[i] == min) && (i < N) )
{
// We have found the current minimum
found = 1;
// move past all in the array that are that minimum
i++;
}
// If we are at the end of the array
if( i == N )
{
// Increment min once more and get out.
min++;
break;
}
// If we found the current minimum in the array
if( found == 1 )
{
// progress to the next minimum
min++;
}
else
{
// We did not find the current minimum - it is missing
// Get out - the current minimum is the missing one
break;
}
}
// Always free memory.
free( A2 );
return min;
}
function solution(A) {
// write your code in JavaScript (Node.js 4.0.0)
var max = 0;
var array = [];
for (var i = 0; i < A.length; i++) {
if (A[i] > 0) {
if (A[i] > max) {
max = A[i];
}
array[A[i]] = 0;
}
}
var min = max;
if (max < 1) {
return 1;
}
for (var j = 1; j < max; j++) {
if (typeof array[j] === 'undefined') {
return j
}
}
if (min === max) {
return max + 1;
}
}
function solution(A) {
// write your code in JavaScript (Node.js 6.4.0)
var missing = 1;
// sort the array.
A.sort(function(a, b) { return a-b });
// try to find the 1 in sorted array if there is no 1 so answer is 1
if ( A.indexOf(1) == -1) { return 1; }
// just search positive numbers to find missing number
for ( var i = A.indexOf(1); i < A.length; i++) {
if ( A[i] != missing) {
missing++;
if ( A[i] != missing ) { return missing; }
}
}
// if cant find any missing number return next integer number
return missing + 1;
}
public static int solution(final int[] A)
{
Arrays.sort(A);
int min = 1;
// Starting from 1 (min), compare all elements, if it does not match
// that would the missing number.
for (int i : A) {
if (i == min) {
min++;
}
}
return min;
}
public func solution(_ A : inout [Int]) -> Int {
// write your code in Swift 3.0 (Linux)
var solution = 1
var hashSet = Set<Int>()
for int in A
{
if int > 0
{
hashSet.insert(int)
while hashSet.contains(solution)
{
solution += 1
}
}
}
return solution
}
public int solution(int[] A) {
int smallestMissingInteger = 1;
if (A.length == 0) {
return smallestMissingInteger;
}
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < A.length; i++) {
if (A[i] > 0) {
set.add(A[i]);
}
}
while (set.contains(smallestMissingInteger)) {
smallestMissingInteger++;
}
return smallestMissingInteger;
}
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
int solution(int A[], int N) {
// write your code in C99 (gcc 6.2.0)
int i;
bool *bin = (bool *)calloc((N+1),sizeof(bool));
for (i = 0; i < N; i++)
{
if (A[i] > 0 && A[i] < N+1)
{
bin[A[i]] = true;
}
}
for (i = 1; i < N+1; i++)
{
if (bin[i] == false)
{
break;
}
}
return i;
}
public func solution(_ A: inout [Int]) -> Int {
var minNum = 1
var hashSet = Set<Int>()
for int in A {
if int > 0 {
hashSet.insert(int)
}
}
while hashSet.contains(minNum) {
minNum += 1
}
return minNum
}
var array = [1,3,6]
solution(&array)
function solution(A) {
let sortedOb = {};
let biggest = 0;
A.forEach(el => {
if (el > 0) {
sortedOb[el] = 0;
biggest = el > biggest ? el : biggest;
}
});
let arr = Object.keys(sortedOb).map(el => +el);
if (arr.length == 0) return 1;
for(let i = 1; i <= biggest; i++) {
if (sortedOb[i] === undefined) return i;
}
return biggest + 1;
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
public int solution(int[] A) {
Arrays.sort(A);
ArrayList<Integer> positive = new ArrayList<>();
for (int i = 0; i < A.length; i++) {
if(A[i] > 0)
positive.add(A[i]);
}
if(positive.isEmpty()) return 1;
if(positive.get(0) > 1) return 1;
for(int i = 0; i < positive.size() - 1; i++) {
if(positive.get(i + 1) - positive.get(i) > 1)
return positive.get(i) + 1;
}
return positive.get(positive.size() - 1) + 1;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] A = {-5,1,2,3,4,6,7,8,9,5};
System.out.println(solution.solution(A));
}
}
public int solution(int[] A) {
Arrays.sort(A);
for (int i = 1; i < 1_000_000; i++) {
if (Arrays.binarySearch(A, i) < 0){
return i;
}
}
return -1;
}