Problem Source: Find All Numbers disappeared in an Array
Long time no brush problem, feel the brain began to dull, so decided to regain the fun of the brush problem. Not too difficult at first, choose some high-rate topics to do, and then see the topic. I am a little surprised, although I know two solutions to this problem, but it is still difficult, incredibly pass rate so high. Then just search for the relevant page and see a topic close to it "Find all duplicates in an Array" and then relieved. These two topics have the same problem, but the problems are slightly different, the solution has similarities. It is estimated that the number is too close to be the first one, and the second one is easy to do. This paper mainly analyzes "find all Numbers disappeared in an array", by the way a simple explanation of "find all duplicates in an array".
The meaning of this question is: given an array of length n, the array element is 1~n. However, some elements appear once, and some elements appear two times, which can also cause some elements not to appear. Now let's find out which elements are not present. Another topic is to let us find the elements that appear two times. Time complexity O (n), Spatial complexity O (1).
Solution One
The first approach is to use the method described in the previous blog, "Another method of array statistical analysis"-the element homing method. The element homing method is easy to understand, which is to swap n elements to where it should be. For example, element 5 is placed at position 4 (subscript starting from 0). One thing to note here is that swapping an element to the correct position may cause the element in the current position to not be in the correct position and need to continue swapping until it cannot be exchanged, as the pseudo-code is as follows:
fori=1:n while canSwap(i) do swap(i);
Once we have the elements in place, it's easy to get what doesn't appear. When a location is not the correct element, it means that the element does not appear.that is, we only need to return the subscript for elements that do not appear, and we only need to return the value of that position for the element that appears two times.
Here is a question, pseudo code has two for loop, complexity is not O ( < Span class= "Mi" id= "mathjax-span-4" style= "font-family:mathjax_math-italic;" >n 2 ?)? No, the complexity is still O (n), which can be explained by the averaging analysis: if the exchange condition is met, each time an element is in the correct position, because there is a total of n elements, so it is necessary to n-1 the exchange (n-1 elements, the nth element is automatically satisfied) so that all elements in the correct position , that is, the while loop executes at most O (n) times, and the cost of each is O (1). So the complexity of the above switching operation is O (n).
The C language code is as follows:
void Swap (int *a,int *b) {inttemp=*a;*a=*b;*b=temp; }int* Finddisappearednumbers (int* Nums,intNumssize,int* returnsize) {int* Result= (int*)malloc (sizeof (int)*numssize); for(intI=0; i<numssize;i++) { while(nums[i]!=i+1&&nums[nums[i]-1]!=nums[i]) {Swap (&nums[i],&nums[nums[i]-1]); } }*returnsize=0; for(intI=0; i<numssize;i++) {if(nums[i]!=i+1) {result[*returnsize]=i+1;*returnsize=*returnsize+1; } }returnResult;}
Solution Two
In the spinster public number "Array statistical analysis", Chenli teacher once gave another kind of solution-take the remainder method, the truth is also relatively good understanding. The array has an element range of 1~n, and the first Loop first adds (n+1) the corresponding position of each element, and the second loop divides each position by (n+1), if the position is 0, indicating that an element does not appear, or two times if the position equals 2.
What is the principle? In the first loop, we actually turn each position into k* (n+1) +i, where k represents the number of times that the position is added (n+1), with a value of 0, 1, and 2,i representing the element at that location. In the second cycle, because the range of I is 1~n, dividing (n+1) is equal to 0, so we get the value of K. based on the value of K, it is easy to know which elements are not present and which elements appear more than once.
The C language code is as follows:
int* Finddisappearednumbers (int* Nums,intNumssize,int* returnsize) {int* Result= (int*)malloc (sizeof (int)*numssize);*returnsize=0; for(intI=0; i<numssize;i++) {nums[nums[i]%(Numssize+1)-1]+= (numssize+1); } for(intI=0; i<numssize;i++) {if(Nums[i]/(numssize+1)==0) {result[*returnsize]=i+1;*returnsize=*returnsize+1; } }returnResult;}
Solution Three
In top solution, some netizens share a wonderful solution-take negative method. The meaning is: take the position of the element negative. A simple sentence may not be easy to understand, let us give an example. Assuming that element I is placed at position K, there are two possible values for I in the negative process: positive, indicating that the element k is not currently encountered minus the position, and negative, which means that the element k is currently present and takes the element negative. But we don't care about K, we care about element I. Since the element I appears, we will look at position I: positive, indicating that this is the first occurrence of the element I, we will position I negative, for negative, indicating that the element I has appeared once, we do not do any action. regardless of whether an element occurs once or two times, it will be negative as long as it appears in its corresponding position. When an element does not appear, the location of the element is always inaccessible, so it is a positive value, and in this way we can find which elements are not present.
From the above analysis, it is also easy to know that, in the process of negative, if we find that the negative position has been negative, indicating that the element has occurred, that is, the element appears two times, we can keep the element.
The C language code is as follows:
int* Finddisappearednumbers (int* Nums,intNumssize,int* returnsize) {int* Result= (int*)malloc (sizeof (int)*numssize); for(intI=0; i<numssize;i++) {int Index=ABS(Nums[i])-1;if(nums[Index]>0) nums[Index]=-nums[Index]; }*returnsize=0; for(intI=0; i<numssize;i++) {if(nums[i]>0) {result[*returnsize]=i+1;*returnsize=*returnsize+1; } }returnResult;}
For the Find all duplicates in an Array, the C language code implemented with the negative method is as follows:
int* Findduplicates (int* Nums,intNumssize,int* returnsize) {int* Result= (int*)malloc (sizeof (int)*numssize);*returnsize=0; for(intI=0; i<numssize;i++) {int Index=ABS(Nums[i])-1;if(nums[Index]>0) {nums[Index]=-nums[Index]; }Else{result[*returnsize]=Index+1;*returnsize=*returnsize+1; } }returnResult;}
Leetcode Find all Numbers disappeared in an Array