zoukankan      html  css  js  c++  java
  • 137.Single Number II---位运算---《剑指offer》40

    题目链接:https://leetcode.com/problems/single-number-ii/description/

    题目大意:给出一串数,每个数都出现三次,只有一个数只出现一次,把这个出现一次的数找出来。

    法一:利用hashMap,空间换时间,但是好像也没怎么换到时间。代码如下(耗时15ms):

     1     public int singleNumber(int[] nums) {
     2         Map<Integer, Integer> map = new HashMap<Integer, Integer>();
     3         int ans = -1;
     4         for(int i = 0; i < nums.length; i++) {
     5             if(map.containsKey(nums[i])) {
     6                 map.put(nums[i], map.get(nums[i]) + 1);
     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                 ans = nums[i];
    15                 break;
    16             }
    17         }
    18         return ans;
    19     }
    View Code

    法二:先排序,再一一计算。代码如下(耗时5ms):

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

    法三(借鉴):利用位运算,这个方法是普遍方法,136题也可以用这个方法做,但是时间复杂度其实是o(n^2),所以也不是最优的,只是用到了位运算。借鉴自:http://blog.csdn.net/feliciafay/article/details/19004479。代码如下(耗时7ms):

     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 %= 3;
    12                 }
    13             }
    14             if(sum != 0) {//如果对3取模后非0,则说明当前位一定是要找的数的某一位
    15                 ans |= sum << i;//将其转为十进制加入结果当中
    16             }
    17         }
    18         return ans;
    19     }
    View Code

    法四(借鉴):这个位运算还没看懂。https://www.cnblogs.com/yangrouchuan/p/5323327.html

     1 链接:https://www.nowcoder.com/questionTerminal/e02fdb54d7524710a7d664d082bb7811
     2 来源:牛客网
     3 
     4 /**
     5      * 数组中有两个出现一次的数字,其他数字都出现两次,找出这两个数字
     6      * @param array
     7      * @param num1
     8      * @param num2
     9      */
    10     public static void findNumsAppearOnce(int [] array,int num1[] , int num2[]) {
    11         if(array == null || array.length <= 1){
    12             num1[0] = num2[0] = 0;
    13             return;
    14         }
    15         int len = array.length, index = 0, sum = 0;
    16         for(int i = 0; i < len; i++){
    17             sum ^= array[i];
    18         }
    19         for(index = 0; index < 32; index++){
    20             if((sum & (1 << index)) != 0) break;
    21         }
    22         for(int i = 0; i < len; i++){
    23             if((array[i] & (1 << index))!=0){
    24                 num2[0] ^= array[i];
    25             }else{
    26                 num1[0] ^= array[i];
    27             }
    28         }
    29     }
    30 /**
    31      * 数组a中只有一个数出现一次,其他数都出现了2次,找出这个数字
    32      * @param a
    33      * @return
    34      */
    35     public static int find1From2(int[] a){
    36         int len = a.length, res = 0;
    37         for(int i = 0; i < len; i++){
    38             res = res ^ a[i];
    39         }
    40         return res;
    41     }
    View Code
  • 相关阅读:
    中国建设银行接口使用详细说明
    Web Service入门
    支付宝及时到帐接口使用详解深入版
    C#仿QQ皮肤-ComboBox 控件实现
    SQl 2005 For XMl 简单查询(Raw,Auto,Path模式)(2)
    GridView 使用方法总结 (二)
    小谈c#数据库存取图片的方式
    SQl 2005 For XMl 简单查询(Raw,Auto,Path模式)(1)
    GridView 使用方法总结 (一)
    C# UDP 入门
  • 原文地址:https://www.cnblogs.com/cing/p/7814105.html
Copyright © 2011-2022 走看看