• 137. Single Number II


    题目:

    Given an array of integers, every element appears three times except for one. Find that single one.

    Note:
    Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

    Hide Tags
     Bit Manipulation
     

    链接:http://leetcode.com/problems/single-number-ii/

    题解:

    主要参考了leetcode discussion以及daijinqiao的博文。

    位运算,使用二进制模拟三进制。twos记录至当前变量为止,1出现2次的digit,ones记录至当前变量为止,1出现1次的digits, 所以ones & twos统计至当前变量为止含有3个1出现的digits, xthrees是对one & twos取反,之后与ones和twos分别作按位与运算,表示清零出现3次1的情况digit。最后返回的ones就是全数组中每个bit位只出现1次的数字。

    扩展情况是假如每个数出现3次,只有一个数出现两次,那么返回twos就是结果。

    Time Complexity - O(n), Space Complexity - O(1)

    public class Solution {
        public int singleNumber(int[] nums) {
            if(nums == null || nums.length == 0)
                return 0;
            int ones = 0, twos = 0, xthrees = 0;
            
            for(int i = 0; i < nums.length; i ++){
                twos |= (ones & nums[i]);
                ones ^= nums[i];
                xthrees = ~(ones & twos);
                ones &= xthrees;
                twos &= xthrees;
            }
            
            return ones;
        }
    }

    还有一种方法是建立一个32位的array,把所有数组中数字的每bit位值加起来,再模3,最后剩下的就是只出现一次的数字。其实也算constant extra space和linear time。

    Time Complexity - O(n), Space Complexity - O(1)。

    public class Solution {
        public int singleNumber(int[] nums) {
            if(nums == null || nums.length == 0)
                return 0;
            int[] count = new int[32];
            int result = 0;
            
            for(int i = 0; i < 32; i++){
                for(int j = 0; j < nums.length; j++){
                   if(((nums[j] >> i) & 1) > 0)           //check if the ith bit of  the current number is 1
                        count[i]++;
                }
                result |= (count[i] % 3) << i;       // equals to    count[i] %= 3;   result += count[i] << i;
            }
            
            return result;
        }
    }

    Update:

    有关bit manipulation, 还需要多看一看<Hacker's Delight>以及Bit Twiddling Hacks -  https://graphics.stanford.edu/~seander/bithacks.html

    public class Solution {
        public int singleNumber(int[] nums) {
            if(nums == null || nums.length == 0)
                return 0;
            int ones = 0, twos = 0, xThrees = 0;
            
            for(int i = 0; i < nums.length; i++) {
                twos |= (ones & nums[i]);     //first calculate twos, based one ones
                ones ^= nums[i];              //then update ones
                xThrees = ~(ones | twos);     //threes is counter of ones and twos
                ones &= xThrees;              //use xThrees to clear some digits of ones
                twos &= xThrees;              //use xThrees to clear some digits of twos
            }
            
            return ones;
        }
    }

    另一种方法的update,  

    public class Solution {
        public int singleNumber(int[] nums) {
            if(nums == null || nums.length == 0)
                return 0;
            int[] bits = new int[32];                   //bit counter
            int res = 0;
            
            for(int i = 0; i < 32; i++) {
                for(int j = 0; j < nums.length; j++) 
                    bits[i] += (nums[j] >> i) & 1;     //add up ith digit of all numbers
                bits[i] %= 3;                          //mod the sum by 3
                res += bits[i] << i;                   //add this digit to final result - the single number
            }
            
            return res;
        }
    }

    二刷:

    Java:

    三变量清零

    public class Solution {
        public int singleNumber(int[] nums) {
            if (nums == null || nums.length == 0) return 0;
            int ones = 0, twos = 0, xThrees = 0;
            for (int num : nums) {
                twos |= (ones & num);
                ones ^= num;
                xThrees = ~(ones & twos);
                ones &= xThrees;
                twos &= xThrees;
            }
            return ones;
        }
    }

    开int[32] 数组清零, 把数组读取放在外循环速度反而比放在内循环慢,不知道是为什么

    public class Solution {
        public int singleNumber(int[] nums) {
            if (nums == null || nums.length == 0) return 0;
            int[] bitmap = new int[32];
            for (int num : nums) {
                for (int i = 0; i < 32; i++) {
                    bitmap[i] += (num >> i) & 1;
                }
            }
            int res = 0;
            for (int i = 0; i < 32; i++) res += ((bitmap[i] % 3) << i);
            return res;
        }
    }

    Reference:

    https://leetcode.com/discuss/857/constant-space-solution 

    http://www.cnblogs.com/daijinqiao/p/3352893.html

    http://blog.csdn.net/a775700879/article/details/11393885

    位运算:(胡乱丢一些link,以后再看)

    http://graphics.stanford.edu/~seander/bithacks.html

    http://bits.stephan-brumme.com/null.html

    http://en.wikipedia.org/wiki/Bitwise_operation

    http://www.cnblogs.com/foohack/p/3772910.html

    http://blog.csdn.net/morewindows/article/details/7354571

    http://www.matrix67.com/blog/archives/263

    http://blog.csdn.net/zmazon/article/details/8262185

    http://bisqwit.iki.fi/story/howto/bitmath/

    https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=%E4%BD%8D%E8%BF%90%E7%AE%97+%E4%B9%A6%E7%B1%8D&start=20

    http://www.cppblog.com/biao/archive/2012/03/20/168357.html

    http://www.zhihu.com/question/27158924

    http://bisqwit.iki.fi/story/howto/bitmath/

    http://www.quora.com/Are-there-any-good-bit-manipulation-tutorials-for-C-C++

    https://leetcode.com/discuss/9763/accepted-proper-explaination-does-anyone-have-better-idea 

    https://leetcode.com/discuss/6632/challenge-me-thx

    https://leetcode.com/discuss/44345/java-bit-manipulation-solution

    https://leetcode.com/discuss/43377/the-simplest-solution-ever-with-clear-explanation

    https://leetcode.com/discuss/31595/detailed-explanation-generalization-bitwise-operation-numbers

    https://leetcode.com/discuss/54970/an-general-way-to-handle-all-this-sort-of-questions

  • 相关阅读:
    oracle数据库连接不上
    Oracle的regexp_instr函数简单用法
    Oracle中dbms_random.string 的用法
    oracle 简单输出语句与赋值
    oracle中sequence(自增序号)的用法
    oracle 函数的返回值与out参数
    SQL%ROWCOUNT作用
    100多个基础常用JS函数和语法集合大全
    题解【AcWing272】最长公共上升子序列
    题解【POJ1062】昂贵的聘礼
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4438794.html
Copyright © 2020-2023  润新知