leetcode-数组中只出现一次的数字
一、版本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 }