In other words, find the lowest positive integer that does not exist in the array. The array can contain duplicates and negative numbers as well. This question was asked by Stri
PMCarpan's algorithm works.
I think your approach works, but you should specify the type of sort you're doing so that it is clear it is a linear sort and not necessarily a full sort of the entire array. This results in O(N) time without using any space.
Scan the array, as you're scanning if the value in your current index is less than the length of the array then swap it with the value currently in that index. You must continue swapping until it no longer makes sense to swap at each index. Then at the end do one more scan until you find an index that isn't correct.
Here's some working python code, although python is not the place to do this sort of thing, lol.
def sortOfSort(arr) :
for index in range(len(arr)) :
checkValue = arr[index]
while(checkValue > 0 and checkValue != index and checkValue < len(arr) and arr[checkValue] != checkValue) :
arr[index] = arr[checkValue]
arr[checkValue] = checkValue
checkValue = arr[index]
return arr[1:] + [arr[0]]
def findFirstMissingNumber(arr) :
for x in range(len(arr)) :
if (x+1 != arr[x]) :
return x+1
return len(arr) + 1
the return arr[1:] part is because based on your description we aren't including zero as a starting point.
My solution in Python:
def lowest_positive(lista):
result = 0
dict = {}
for i in lista:
if i <= 0:
continue
if i in dict:
continue
else:
dict[i] = i
if result == 0:
result = result +1
if result < i:
continue
result = result +1
while result in dict:
result = result +1
return result
Test cases:
lista = [5, 3, 4, -1, 1, 2]
lista = [1,2,3,4,5]
lista = [3, 4, -1, 1]
lista = [2, 3, 4, 1]
lista = [1,0]
lowest_positive(lista)
Please note, I am not considering 0 as positive number
Logic: If number is less than 0, it is rejected. Then the number is checked in dictionary if it exist, if yes, the next number is read else it is added to the dictionary. result is the counter which is incremented one by one. if result is less than the number read in the list, the next number is read else, the counter is increased by one and this result is also checked in dictionary. Dictionary in all will store all the number read in the list, plus any missing positive numbers in between the smallest number read in the list.
Here is a C implementation
INPUT
#include <stdio.h>
#include <stdlib.h>
//Here we separate the positive and negative number
int separate (int arr[], int size)
{
int j = 0, i , temp;
for(i = 0; i < size; i++)
{
if (arr[i] <= 0)
{
/*Here we using bitwise operator to swap the
numbers instead of using the temp variable*/
arr[j] = arr[j]^arr[i];
arr[i] = arr[j]^arr[i];
arr[j] = arr[j]^arr[i];
j++;
}
}
printf("First We Separate the negetive and positive number \n");
for( i = 0 ; i <size ; i++)
{
printf("Array[%d] = %d\n",i,arr[i]);
}
return j;
}
int findMissingPositive(int arr[], int size)
{
printf("Remove the negative numbers from array\n");
int i;
for( i = 0 ; i <size ; i++)
{
printf("Array[%d] = %d\n",i,arr[i]);
}
for(i = 0; i < size; i++)
{
if(abs(arr[i]) - 1 < size && arr[ abs(arr[i]) - 1] > 0)
arr[ abs(arr[i]) - 1] = -arr[ abs(arr[i]) - 1];
}
for(i = 0; i < size; i++)
if (arr[i] > 0)
{
return i+1;
}
return size+1;
}
int findMissing(int arr[], int size)
{
int j = separate (arr, size);
return findMissingPositive(arr+j, size-j);
}
int main()
{
int size ;
printf("Enter the Value of Size of Array : ");
scanf("%d",&size);
int arr[size];
printf("Enter the values :\n");
for( int i = 0 ; i < size ; i++)
{
printf("Array[%d] = ",i);
scanf("%d",&arr[i]);
}
int missing = findMissing(arr,size);
printf("The smallest positive missing number is %d ", missing);
return 0;
}
Enter the Value of Size of Array : 8
Enter the values :
Array[0] = 1
Array[1] = -1
Array[2] = -5
Array[3] = -3
Array[4] = 3
Array[5] = 4
Array[6] = 2
Array[7] = 8
First We Separate the negetive and positive number
Array[0] = -1
Array[1] = -5
Array[2] = -3
Array[3] = 1
Array[4] = 3
Array[5] = 4
Array[6] = 2
Array[7] = 8
Remove the negative numbers from array
Array[0] = 1
Array[1] = 3
Array[2] = 4
Array[3] = 2
Array[4] = 8
The smallest positive missing number is 5
Process returned 0 (0x0) execution time : 27.914 s
Press any key to continue.
/*
How work :
[if(abs(arr[i]) - 1 < size && arr[ abs(arr[i]) - 1] > 0)
arr[ abs(arr[i]) - 1] = -arr[ abs(arr[i]) - 1];]
before: arr = { 7, 3, 4, 5, 5, 3, 2}
i == 0: arr[0] = 7
arr[7-1] is 2 > 0 ~> negate
arr = { 7, 3, 4, 5, 5, 3, -2}
i == 1: arr[1] = 3
arr[3-1] is 4 > 0 ~> negate
arr = { 7, 3, -4, 5, 5, 3, -2}
i == 2: arr[2] is -4 ~> abs for indexing
arr[4-1] is 5 > 0 ~> negate
arr = { 7, 3, -4,-5, 5, 3, -2}
i == 3: arr[3] is -5 ~> abs for indexing
arr[5-1] is 5 > 0 ~> negate
arr = { 7, 3, -4, -5, -5, 3, -2}
i == 4: arr[4] is -5 ~> abs for indexing
arr[5-1] is -5 < 0 ~> print abs(-5) as duplicate
i == 5: arr[5] is 3
arr[3-1] is -4 < 0 ~> print abs(3) as duplicate
i == 6: arr[6] is -2 ~> abs for indexing
arr[2-1] is 3 > 0 ~> negate
arr = { 7, -3, -4, -5, -5, 3, -2}
indices of positive entries: 0, 5 ~> 1 and 6 not in original array
indices of negative entries: 1, 2, 3, 4, 6 ~> 2, 3, 4, 5, 7 in original array
*/
Drawback of the above approach is it takes extra space for assigning "max_value" which is not the right solution
def missing_positive_integer(my_list):
max_value = max(my_list)
my_list = [num for num in range(1,max(my_list)) if num not in my_list]
if len(my_list) == 0:
my_list.append(max_value+1)
return min(my_list)
my_list = [1,2,3,4,5,8,-1,-12,-3,-4,-8]
missing_positive_integer(my_list)
Here's another python implementation with o(n) time complexity and o(1) space complexity
def segregate(arr):
length = len(arr)
neg_index = length
for i, value in enumerate(arr):
if(value < 1 and neg_index == length):
neg_index = i
if(neg_index != length and value >= 1):
temp = arr[i]
arr[i] = arr[neg_index]
arr[neg_index] = temp
neg_index += 1
return arr[:neg_index]
def missingPositiveNumber(arr):
arr = segregate(arr)
length = len(arr)
for i, value in enumerate(arr):
if(value - 1 < l):
arr[abs(value) - 1] = -(abs(arr[abs(value) - 1]))
for i, value in enumerate(arr):
if(value > 0):
return i + 1
return length + 1
print(missingPositiveNumber([1, -1, 2, 3]))
Assuming the array can be modified,
We divide the array into 2 parts such that the first part consists of only positive numbers. Say we have the starting index as 0
and the ending index as end
(exclusive).
We traverse the array from index 0
to end
. We take the absolute value of the element at that index - say the value is x
.
x > end
we do nothing.x-1
negative. (Clarification: We do not toggle the sign. If the value is positive, it becomes negative. If it is negative, it remains negative. In pseudo code, this would be something like if (arr[x-1] > 0) arr[x-1] = -arr[x-1]
and not arr[x-1] = -arr[x-1]
.)Finally, we traverse the array once more from index 0
to end
. In case we encounter a positive element at some index, we output index + 1
. This is the answer. However, if we do not encounter any positive element, it means that integers 1
to end
occur in the array. We output end + 1
.
It can also be the case that all the numbers are non-positive making end = 0
. The output end + 1 = 1
remains correct.
All the steps can be done in O(n)
time and using O(1)
space.
Example:
Initial Array: 1 -1 -5 -3 3 4 2 8
Step 1 partition: 1 8 2 4 3 | -3 -5 -1, end = 5
In step 2 we change the signs of the positive numbers to keep track of which integers have already occurred. For example, here array[2] = -2 < 0
, it suggests that 2 + 1 = 3
has already occurred in the array. Basically, we change the value of the element having index i
to negative if i+1
is in the array.
Step 2 Array changes to: -1 -8 -2 -4 3 | -3 -5 -1
In step 3, if some value array[index]
is positive, it means that we did not find any integer of value index + 1
in step 2.
Step 3: Traversing from index 0 to end, we find array[4] = 3 > 0
The answer is 4 + 1 = 5