Problem one: In an array of integers, in addition to a number, the number of other occurrences is two times, the occurrence of the number of times, the need for time complexity as small as possible. For example, the array {1,2,2,3,3,6,6}, the number that occurs once is 1.
As can be seen from the description of the topic, only one number in the array appears once, the other numbers appear two times, associating with the characteristics of the XOR operation: any number and the result of their own XOR or operation is 0, any number and the result of the 0 operation is itself. According to the above characteristics, you can consider starting from the first element of the array, one by one and the following elements to do the XOR or operation, the final result is to find only the number of occurrences.
The algorithm is implemented as follows:
Public classMain { Public Static voidMain (string[] args) {int[] Nums =New int[]{1,2,2,3,3,4,4,1,23}; System.out.println (Getnumappearsonce (nums)); } Public Static intGetnumappearsonce (int[] nums) { if(Nums = =NULL|| Nums.length <= 2){ Throw NewIllegalArgumentException ("nums size must bigger than 2"); } intresult = 0; for(inti=0;i<nums.length;i++) {result^=Nums[i]; } returnresult; }}
The time complexity of the above algorithm is O (n), where n is the length of the array, since the result can be found only by traversing through the arrays.
Divergent thinking: If the required array contains two number of times the number of occurrences is 1, the other occurrences are 2, how to find the two number?
According to the above problem one idea, we still from the beginning in place the array to do the XOR or operation, the final result should be two different numbers to do the difference or the value after the operation. Because the two numbers are not the same, the final result is certainly not 0, the tangent result corresponding to the bits of at least one is 1, we find the first bits in the position of the 1, that is, N, and then according to the ground n is 1 or 0 of the array into two sub-arrays, the first subarray of each number of bits nth bit is 1 The other one is 0, so after the split, the same number will certainly be divided into the same sub-array, and each sub-array contains only one occurrence of the number, according to problem one, we can easily find two occurrences of the number, the implementation of the following:
Public classMain { Public Static voidMain (string[] args) {int[] Nums =New int[]{1,2,2,3,3,4,4,1,23,43}; System.out.println (Getnumsappearsonce (nums)); } Public Static intGetnumappearsonce (int[] nums) { if(Nums = =NULL|| Nums.length <= 2){ Throw NewIllegalArgumentException ("nums size must bigger than 2"); } intresult = 0; for(inti=0;i<nums.length;i++) {result^=Nums[i]; } returnresult; } Public StaticList<integer> Getnumsappearsonce (int[] nums) { if(Nums = =NULL|| Nums.length <= 2){ Throw NewIllegalArgumentException ("nums size must bigger than 2"); } List<Integer> result =NewArraylist<integer> (2); inttemp =getnumappearsonce (nums); intindex =Findfirstbitidone (temp); intNUM1 = 0,num2 = 0; for(inti=0;i<nums.length;i++){ if(Isbitone (Nums[i],index)) {NUM1^=Nums[i]; }Else{num2^=Nums[i]; }} result.add (NUM1); Result.add (NUM2); returnresult; } Private Static BooleanIsbitone (intNumintindex) {num= num >>index; return(num & 1) = = 1; } Private Static intFindfirstbitidone (inttemp) { intindex = 0; while((temp & 1) = = 0) {Temp= Temp >> 1; Index++; } returnindex; }}
Only one occurrence of the number in the array