zoukankan      html  css  js  c++  java
  • leetcode[137] Single Number II

    题目和上题类似,这里给的数组仅有一个数出现一次,其他的出现3次。返回那个出现一次的数。

    这题还是比较难想到的。不想上一题只要异或一下就可以了,不用额外操作。

    法一:还是用map方法

    class Solution {
    public:
    int singleNumber(int A[], int n)
    {
        unordered_map<int , int> umap;
        for (int i = 0; i < n; i++)
        {
            umap[A[i]]++;
        }
        for (int i = 0; i < n; i++)
        {
            if (umap[A[i]] == 1)
                return A[i];
        }
    }
    };

    法二:还是利用位运算才有办法实现不用额外空间,就是遍历32次每次记录某位的出现的次数,如果不能被三整除,说明那个出现一次的就在该位有值,那么ans 或该位一下就可以了。

    int singleNumber(int A[], int n)
    {
        int ans = 0;
        for (int i = 0; i < 32; i++)
        {
            int cnt = 0, bit = 1 << i;
            for (int j = 0; j < n; j++)
            {
                if (A[j] & bit) cnt++;
            }
            if (cnt % 3 != 0)
                ans |= bit;
        }
        return ans;
    }

    法三:还是位运算,这里利用二进制模拟a进制的方法。对于此题,a为3.

    这里分析和拓展的很好:

    对于除出现一次之外的所有的整数,其二进制表示中每一位1出现的次数是3的整数倍,将所有这些1清零,剩下的就是最终的数。用ones记录到当前计算的变量为止,二进制1出现“1次”(mod 3 之后的 1)的数位。用twos记录到当前计算的变量为止,二进制1出现“2次”(mod 3 之后的 2)的数位。当ones和twos中的某一位同时为1时表示二进制1出现3次,此时需要清零。即用二进制模拟三进制计算。最终ones记录的是最终结果。

    int singleNumber(int A[], int n) {
        int ones = 0, twos = 0, xthrees = 0;
        for(int i = 0; i < n; ++i) {
            twos |= (ones & A[i]);
            ones ^= A[i];
            xthrees = ~(ones & twos);
            ones &= xthrees;
            twos &= xthrees;
        }
    
        return ones;
    }

    该文的拓展很值得学习!

  • 相关阅读:
    HERO 3
    office的一些应用,
    网页之间的参数传弟
    一个好的数码网站
    C++遍历中删除std::hash_map元素问题
    【转】Asio与shared_ptr的一些注意事项
    delphi的字节对齐
    paypal的即时付款通知参数列表(PDT)
    vs2010下libevent的使用
    mysql 数据库 left join,right join, inner join 知识
  • 原文地址:https://www.cnblogs.com/higerzhang/p/4159330.html
Copyright © 2011-2022 走看看