zoukankan      html  css  js  c++  java
  • 136.Single Number---异或、位运算

    题目链接

    题目大意:给出一串数组,里面的数都是两个,只有一个数是一个,把这个只有一个的数找出来。时间复杂度最好是线性的,空间复杂度最好为O(1).

    法一:利用map,空间换时间,代码如下(耗时26ms):

     1     public int singleNumber(int[] nums) {
     2         Map<Integer, Integer> map = new HashMap<Integer, Integer>();
     3         int res = -1;
     4         for(int i = 0; i < nums.length; i++) {
     5             if(map.get(nums[i]) != null && map.get(nums[i]) == 1) {
     6                 map.put(nums[i], 2);
     7             }
     8             else {
     9                 map.put(nums[i], 1);
    10             }
    11         }
    12         for(int i = 0; i < nums.length; i++) {
    13             if(map.get(nums[i]) == 1) {
    14                 res = nums[i];
    15                 break;
    16             }
    17         }
    18         return res;
    19     }
    View Code

    法二:先排序,再一个for循环,依次比较,代码如下(耗时8ms):

     1     public int singleNumber(int[] nums) {
     2         Arrays.sort(nums);
     3         int res = nums[0];
     4         int cnt = 1;
     5         boolean flag = false;
     6         for(int i = 1; i < nums.length; i++) {
     7             if(nums[i] != nums[i - 1]) {
     8                 if(cnt == 1) {
     9                     res = nums[i - 1];
    10                     flag = true;
    11                     break;
    12                 }
    13                 cnt = 1;
    14             }
    15             else {
    16                 cnt++;
    17             }
    18         }
    19         if(flag == false) {
    20             res = nums[nums.length - 1];
    21         }
    22         return res;
    23     }
    View Code

    法三(借鉴):利用异或,由3^3=0知道,相同的两个数异或为0,不同的两个数异或为1。代码如下(耗时1ms):

    1     public int singleNumber(int[] nums) {
    2         int res = nums[0];
    3         for(int i = 1; i < nums.length; i++) {
    4             res = res ^ nums[i];
    5         }
    6         return res;
    7     }
    View Code

     法四(借鉴):利用137题的法三,位运算,只是把对3取模改成对2取模即可。(num>>i)&1取num的第i位二进制数。ans |= sum <<i将二进制相加转为十进制。代码如下(耗时12ms):

     1     public int singleNumber(int[] nums) {
     2         int ans = 0;
     3         int length = nums.length;
     4         //将每一个数取二进制位按位相加,如果都是重复的则当前位的相加和一定是3的倍数,否则当前位一定存在于要找的那个数中
     5         //比如1,1,1,2,2,2,3这六个数将其转为二进制数按位相加,然后每一位都对3取模,最后一定可以得到3
     6         for(int i = 0; i < 32; i++) {//计算每一位
     7             int sum = 0;//统计每一位的和
     8             for(int j = 0; j < length; j++) {//对每个数取第i位的数值
     9                 if(((nums[j] >> i) & 1) == 1) {//取第i位的数值
    10                     sum++;//将每个数第i位的值相加求和
    11                     sum %= 2;
    12                 }
    13             }
    14             if(sum != 0) {//如果对3取模后非0,则说明当前位一定是要找的数的某一位
    15                 ans |= sum << i;//将其转为十进制加入结果当中
    16             }
    17         }
    18         return ans;
    19     }
    View Code
  • 相关阅读:
    markdown图片设置
    编程变量名
    c++ 子类构造函数初始化及父类构造初始化
    idea中解决Git反复输入代码的问题
    idea中修改git提交代码的用户名
    网络相关
    idea Controller层编译Mapper层报错
    java7与java8的新特性
    修改列名以及其数据类型
    修改数据库表的某个字段默认值
  • 原文地址:https://www.cnblogs.com/cing/p/7690806.html
Copyright © 2011-2022 走看看