|
||
Title: Minimum non existing number Post by birbal on Mar 26th, 2012, 12:06pm Given an unsorted array of integers, find the minimum of all positive integers that does not exist in the array. For example, [1,2,0] returns 3 [3,4,-1,1] returns 2 Can it be done inO(n) time and O(1) space? |
||
Title: Re: Minimum non existing number Post by towr on Mar 26th, 2012, 12:53pm Are the number in the array distinct? Because if that's the case an O(n) time O(1) solution readily comes to mind. (Start by pivoting around 0 and discarding all number <= 0; Then repeatedly pick a pivot and check if the largest number in the 'small' equals the number of elements in it to see if there's one missing.) |
||
Title: Re: Minimum non existing number Post by Grimbal on Mar 27th, 2012, 2:00am If the array has size n, then the answer is between 1 and n+1. Just use an array of n booleans to check which ones are present. PS: uh... but that wouldn't be O(n) space... |
||
Title: Re: Minimum non existing number Post by Grimbal on Mar 27th, 2012, 8:29am on 03/26/12 at 12:53:30, towr wrote:
Wouldn't that be O(n log n)? |
||
Title: Re: Minimum non existing number Post by towr on Mar 27th, 2012, 8:44am No, because on average you can throw half the array away, you only need to seek further in one of the two parts. It's no different in complexity then finding the kth median. |
||
Title: Re: Minimum non existing number Post by Grimbal on Mar 27th, 2012, 9:26am But then you need more than O(1) space. Unless you can reuse the original array, in which case I do agree. |
||
Title: Re: Minimum non existing number Post by towr on Mar 27th, 2012, 9:47am Quicksort also uses the space of the original array, right? So I think it should work. |
||
Title: Re: Minimum non existing number Post by birbal on Mar 28th, 2012, 7:21pm on 03/26/12 at 12:53:30, towr wrote:
Can you explain your solution. What is 'small' here ? |
||
Title: Re: Minimum non existing number Post by towr on Mar 28th, 2012, 10:30pm Here's an example We start with the array: [3, 8, -1, 17, 2, 13, 7, 5, 16, 20, 6, 15, 10, 11, 4, 19, 9, 1, 14, 18] We pivot around 0 so we can select the positive elements small=[-1] large=[8, 17, 2, 13, 7, 5, 16, 20, 6, 15, 10, 11, 4, 19, 9, 1, 14, 18, 3] discard array with elements smaller or equal to 0. [8, 17, 2, 13, 7, 5, 16, 20, 6, 15, 10, 11, 4, 19, 9, 1, 14, 18, 3] We have 19 elements left, so pick the next pivot to be around half, say 10. small=[8, 3, 2, 1, 7, 5, 9, 4, 6, 10] large=[11, 15, 19, 20, 16, 14, 18, 13, 17] The small array contains 10 elements, so every number <=10 is accounted for (because they're unique, >=1 and <=10) so we can discard the small array. [11, 15, 19, 20, 16, 14, 18, 13, 17] We have 9 elements left, and the minimum is 11, so let's pivot around 15. small=[11, 15, 13, 14] large=[18, 16, 20, 17, 19] There are 4 elements in the small array, but there should be 5 if there wasn't one missing (it should contain 11-15). So we need to search the small array further and can discard the large one. [11, 15, 13, 14] Pick the pivot about halfway 11 and 15, so 13. small=[11, 13] large=[14, 15] The small array has two elements, but should contain 11, 12 and 13 if there wasn't one missing. So again we discard the large array and continue to search the small one. [11, 13] At this point it's probably fastest to just see which one is missing, Rather than to repeat the divide and conquer strategy. In either case we'll find that 12 is the smallest missing element. |
||
Title: Re: Minimum non existing number Post by birbal on Mar 28th, 2012, 10:57pm on 03/28/12 at 22:30:31, towr wrote:
This solution looks O(n log n) to me. Since the step of dividing the array is itselt O(n). One approach that i can think of is: 1. Discard -ve elements (as you did in step 1) 2. Startting from beginning of the array, for each element x, try to place it on index [x-1] of the array. If the element present at index[x-1] is x, then skip it otherwise repeat for that element also. 3. First i such that a[i-1] != i if the answer. |
||
Title: Re: Minimum non existing number Post by birbal on Mar 28th, 2012, 11:15pm int _tmain(int argc, _TCHAR* argv[]) { int a[19] = {8, 17, 2, 13, 7, 5, 16, 20, 6, 15, 10, 11, 4, 19, 9, 1, 14, 18, 3}; int n = 19; for(int i=0; i<n; i++) { if(a[i] > n) continue; if(a[i] < 0) continue; if(a[i] == i+1) continue; else { int loc = a[i] - 1; //ideal location for a[i] if(a[loc] != a[i]) { a[i] = a[loc]; a[loc] = loc+1; i--; } else continue; } } for(int i=0; i<n; i++) if(a[i] != i+1) { printf("%d\n",i+1); return 0; } printf("%d\n",n+1); return 0; } |
||
Title: Re: Minimum non existing number Post by SMQ on Mar 29th, 2012, 5:31am on 03/28/12 at 22:57:31, birbal wrote:
No, since you're discarding elements, each step is smaller than the last. On average, you will traverse n + n/2 + n/4 + n/8 + ... = 2n elements. (Although, like quicksort, it does have an O(n2) worst-case performance for pathological inputs.) --SMQ |
||
Title: Re: Minimum non existing number Post by towr on Mar 29th, 2012, 8:32am on 03/29/12 at 05:31:59, SMQ wrote:
Besides, isn't quicksort guaranteed O(n log n) when you choose the pivot with median of medians? |
||
Title: Re: Minimum non existing number Post by birbal on Mar 29th, 2012, 12:13pm on 03/29/12 at 08:32:37, towr wrote:
I see....This clarifies a lot...Its indeed worst case O(n) |
||
Title: Re: Minimum non existing number Post by towr on Mar 29th, 2012, 1:25pm And an even simpler approach, if you don't mind destroying the array -- and which will work even if you have multiple occurrences -- is to swap every element into its proper place (i.e. element i to arr[i-1]). Throw away doubles and elements out of bound, replacing them with a 0. Then when you reach the end, search for the first 0. Something like for (i=0; i < n i++) { t = a[i]; if (t <=0 || t >=n) { a[i]=0; continue; } while (a[t] > 0) { a[i] = a[t]; a[t] = t; t = a[i]; if (t <=0 || t >=n) { a[i]=0; break; } } } for (i=0; i < n i++) if (a[i] ==0) return i+1; (Probably not entirely correct, it's late and I have a headache.) |
||
Title: Re: Minimum non existing number Post by birbal on Mar 30th, 2012, 5:36am on 03/29/12 at 13:25:50, towr wrote:
Looks similar to the approach that i have given in one of my posts above :) |
||
Title: Re: Minimum non existing number Post by towr on Mar 30th, 2012, 8:55am You're right. And yours even a bit nicer too, cleverly avoiding a nested loop by simply decrementing the counter. Although I don't think yours handles doubles (seems like that would cause a loop); but that can easily be fixed. |
||
Title: Re: Minimum non existing number Post by nova2358 on Apr 3rd, 2012, 9:25am on 03/26/12 at 12:53:30, towr wrote:
Your solution is good. Originally I thought it was impossible to find an O(n) solution. The idea of selecting a pivot can reduce the running time from O(n log n) to O(n). Because we can reduce the running time from T(n) = 2T(n/2) + O(n) to T(n) = T(n/2) + O(n). I have been interviewed with 2 questions like this. Quick select can provide an average O(n) solution and the median of median algorithm can guarantee a O(n) solution in worst case. |
||
Title: Re: Minimum non existing number Post by jianqiang on Apr 7th, 2012, 2:53am first scan the vector , and find the minimal number, let it be Min. n is the size the vector. Then visit each element of the vector again. for (i = 0; i < n; i++) { t = a[i]; if (t < Min) { t += Min; } if (t <= 0 || t > n) { continue; //a[i] can not be the minimal non existing number. } a[t-1] = 2Min-a[t-1]; } then traverse the vector to find the minimal non-existing positive integer and restore vector non_exist = -1; for (i = 0;i < n ; i++) { if (a[i] < Min) { a[i] = 2Min-a[i]; } else if (non_exist < 0) { non_exist = i+1; } } if (non_exist < 0) { non_exist = n + 1; } |
||
Title: Re: Minimum non existing number Post by birbal on Apr 8th, 2012, 2:54am on 03/29/12 at 13:25:50, towr wrote:
How does yours handle duplicate. I guess both the programs will fail in case of dublicates. Yours will go to an infinite loop and mine will terminate without giving valid result. |
||
Title: Re: Minimum non existing number Post by towr on Apr 8th, 2012, 6:36am If you read the description (which isn't faithfully implemented in the code below it -- hence the disclaimers), you can read that I'd just replace duplicates by 0. Just an extra check you need to do before swapping. |
||
Title: Re: Minimum non existing number Post by birbal on Apr 8th, 2012, 7:24am on 04/08/12 at 06:36:25, towr wrote:
Yeah, read it now...:) |
||
Powered by YaBB 1 Gold - SP 1.4! Forum software copyright © 2000-2004 Yet another Bulletin Board |