二进制逻辑运算求解137. Single Number II

来源:互联网 发布:小蜜蜂软件 编辑:程序博客网 时间:2024/05/17 12:00

题目

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

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

题目解析

给定一个整数数组,除了有一个元素只出现1次,其他同一个元素均会在数组中出现三次,要求找出这个元素,并且算法复杂度不能超过O(n)的复杂度,并且算法尽可能少使用额外的空间,难度为medium

思路分析

最直接的做法就是用map的stl容器去辅助判断哪个元素只出现一次,但是这样就很浪费空间,不太符合题目的要求。仔细分析题目的条件,发现可以通过二进制算术运算去求解

举个简单例子,比如一个数组里面的元素为[1,1,1,3],我们可以使用32位bit去表示一个int型数组,因此数组里面的元素用二进制表示为0001,0001,0011(方便分析,只取低4位)

为了方便说明,我们取数组[1,1,1]与上面的数组进行比较,将两个元组的所有元素都转换为二进制,然后从最低一位开始,一个数组的所有元素相同位进行相加,发现当为[1,1,1]时候,每一个位相加的结果mod3都等于0,说明如果同一元素均出现三次的话,那么数组里面每个元素每一位相加之后mod3都等于0


再取[1,1,1,2]做相同类似的处理,发现最低一位相加的结果mod3之后变成1,因此我们找到了这个元素在这一个二进制位的取值就是1,如果相加的结果mod3之后仍然为0,那么我们就知道了这个元素在这一个二进制位的取值为0,因此我们对每一位的取值进行与运算,那么最后就会得到这个元素的值

代码

#include <memory.h>#include <vector>#define Bitnum 32class Solution {public:    int Bit[Bitnum];    int singleNumber(vector<int>& nums) {        memset(Bit,0,sizeof(Bit));        int arraysize = nums.size();        int result = 0;        for (int i = 0; i < Bitnum; ++i) {            for (int j = 0; j < arraysize; ++j) {                if (1 & (nums[j] >> i)) {                    ++Bit[i];                }            }            result |= ((Bit[i] % 3 ) << i);        }        return result;    }};
原创粉丝点击