zoukankan      html  css  js  c++  java
  • Leetcode 之 Single Number

    问题1:问题是一堆数,只有一个数只出现1次,其他数都出现2次,怎么求出这个数?

    我们知道位运算里面的异或操作,当两个数相同时,得到的结果是零。所以我们简单的把所有数一起求异或就得到了答案。

    更一般的,只有1个数出现奇数次,其他数都出现偶数次,都可以这么解决。

    代码如下

    class Solution {
    public:
        int singleNumber(vector<int>& nums) {
            int ones = 0, i;
            for (i = 0; i < nums.size(); ++i) ones ^= nums[i];
            return ones;
        }
    }

    问题2:问题是一堆数,只有2个数只出现1次,其他数都出现2次,怎么求出这个数?

    基于上面的题,我们知道了,只有1个数的情况下怎么求出这个数。如果对于本题,我们用上面的方法,求出的结果是这两个只出现1次的数的异或。

    我们知道如果这两个数异或结果中某一位是1,说明这2个数在这一位是不同的。因此我们可以取出这一位,然后用这一位给数分桶,两桶中的数就分别变成了问题1。

    代码如下

    class Solution {
    public:
        vector<int> singleNumber(vector<int>& nums) {
            int ones = 0, left = 0, right = 0, i;
            for (i = 0; i < nums.size(); ++i) ones ^= nums[i];
            ones &= -ones;//取出最低不为0的一位
            for (i = 0; i < nums.size(); ++i) {
                if (ones & nums[i]) left ^= nums[i];
                else right ^= nums[i];
            }
            return {left, right};
        }
    };

    问题2:问题是一堆数,只有3个数只出现1次,其他数都出现2次,怎么求出这个数?

    基于上面的题,我们又知道了,只有2个数的情况下怎么求出这2个数。如果对于本题,我们只需要稍微改动上面的方法,就得到了答案。

    用上面的方法,分桶求出后,我们得到两个数,其中一个是这三个数的某个数本身,另一个是其他两个数的异或。

    如果对两个桶再分桶一次,那么包含一个数的那个桶,得到了那个数本身和0, 另外一个桶分桶就得到了剩下的两个数。

    代码如下

    class Solution {
    public:
        vector<int> singleNumber(vector<int>& nums) {
            int ones = 0, left = 0, right = 0, a = 0, b = 0, c = 0, d= 0, i;
            for (i = 0; i < nums.size(); ++i) ones ^= nums[i];
            ones &= -ones;//取出最低不为0的一位
            for (i = 0; i < nums.size(); ++i) {
                if (ones & nums[i]) left ^= nums[i];
                else right ^= nums[i];
            }   
            left &= -left;
            right &= -right;
            for (i = 0; i < nums.size(); ++i) {
               if (ones & nums[i])
                   if (left & nums[i]) a ^= nums[i];
                   else b ^= nums[i];
               else 
                   if (right & nums[i]) c ^= nums[i];
                   else d ^= nums[i];
            }   
            if (a == 0) return {b, c, d}; 
            if (b == 0) return {a, c, d}; 
            if (c == 0) return {a, b, d}; 
            return {a, b, c}; 
        }   
    };
  • 相关阅读:
    Android学习笔记(四十):Preference的使用
    java反射中Method类invoke方法的使用方法
    accept函数
    C++教程之lambda表达式一
    《windows核心编程系列》十八谈谈windows钩子
    STL学习小结
    RS-232协议和RS-485协议
    选择排序
    在asp.net mvc中使用PartialView返回部分HTML段
    uva 10560
  • 原文地址:https://www.cnblogs.com/Dream-Fish/p/4828259.html
Copyright © 2011-2022 走看看