一、版本1—有序數組中只出現一次的數字
1、題目描述
給定一個只包含整數的有序數組,每個元素都會出現兩次,唯有一個數只會出現一次,找出這個數。
示例 1:
輸入: [1,1,2,3,3,4,4,8,8]
輸出: 2
示例 2:
輸入: [3,3,7,7,10,11,11]
輸出: 10
注意: 您的方案應該在 O(log n)時間復雜度和 O(1)空間復雜度中運行。
2、思路
a)使用線性時間異或運算:
b)實現規定時間復雜度的方法
3、代碼
a)使用異或運算實現的代碼
1 package cn.zifuchuan; 2 3 public class Test7 { 4 5 public static void main(String[] args) { 6 int[] nums = {1,1,2,3,3,4,4,8,8}; 7 System.out.println(singleNonDuplicate(nums)); 8 } 9 10 public static int singleNonDuplicate(int[] nums) { 11 int temp = 0; 12 for (int i = 0; i < nums.length; i++) { 13 temp ^= nums[i]; 14 } 15 return temp; 16 } 17 }
b)二分法查找實現
1 package cn.zifuchuan; 2 3 public class Test7 { 4 5 public static void main(String[] args) { 6 int[] nums = {1, 1, 2, 2, 4, 4, 5, 5,9}; 7 System.out.println(singleNonDuplicate(nums)); 8 } 9 10 // public static int singleNonDuplicate(int[] nums) { 11 // int temp = 0; 12 // for (int i = 0; i < nums.length; i++) { 13 // temp ^= nums[i]; 14 // } 15 // return temp; 16 // } 17 18 public static int singleNonDuplicate(int[] nums) { 19 int low = 0, high = nums.length - 1; 20 int mid = (high - low) / 2; 21 while(low < mid) { 22 if((nums[mid] == nums[mid - 1])) { //和左邊相等,那么出現一次的就在右邊 23 if((mid - low) % 2 != 0) { 24 low = mid + 1; 25 System.out.println("low=" + low + "nums[low]" + nums[low]); 26 } else { 27 high = mid - 2; 28 System.out.println("high=" + high + "nums[high]" + nums[high]); 29 } 30 } else if(nums[mid] == nums[mid + 1]){ //和右邊相等,出現一次的就在左邊 31 if((mid - low) % 2 != 0) { 32 high = mid - 1; 33 System.out.println("high=" + high + "nums[high]" + nums[high]); 34 } else { 35 low = mid + 2; 36 System.out.println("low=" + low + "nums[low]" + nums[low]); 37 } 38 } 39 mid = (high - low) / 2 + low; //二分中間位置 40 System.out.println("mid=" + mid + "mid:" + nums[mid]); 41 } 42 // System.out.println(mid); 43 return nums[low]; 44 } 45 }
二、版本二—無須數組中找出兩個只出現一次的數字
1、題目描述
給定一個整數數組 nums
,其中恰好有兩個元素只出現一次,其余所有元素均出現兩次。 找出只出現一次的那兩個元素。
示例 :
輸入: [1,2,1,3,2,5] 輸出: [3,5]
注意:
1、結果輸出的順序並不重要,對於上面的例子, [5, 3] 也是正確答案。 2、你的算法應該具有線性時間復雜度。你能否僅使用常數空間復雜度來實現?
2、代碼實現
a)位運算實現
1 public int singleNumber(int[] nums) { 2 int a = 0, b = 0; 3 for (int i = 0; i < nums.length; i++) { 4 a = (a ^ nums[i]) & ~b; 5 b = (b ^ nums[i]) & ~a; 6 } 7 return a; 8 }
b)排序之后實現
1 public static int singleNumber(int[] nums) { 2 int len = nums.length; 3 Arrays.sort(nums); 4 for (int i = 0; i < len; i++) { 5 if(((i + 1) < (len - 1)) && (nums[i] == nums[i + 1]) ) { 6 i = i + 2; 7 continue; 8 } else if(((i+1) < (len - 1)) && (nums[i] != nums[i + 1])){ 9 return nums[i]; 10 } else { 11 return nums[len-1]; 12 } 13 } 14 return 0; 15 }