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     }

 

posted @ 2019-03-20 22:53 风沙迷了眼 阅读(...) 评论(...) 编辑 收藏