https://leetcode.com/problems/single-number-ii/
很无耻的又一次使用了黑暗料理...
class Solution: # @param {integer[]} nums # @return {integer} def singleNumber(self, nums): # 又是一道黑暗料理.. return (sum(set(nums))*3 - sum(nums))/2
速度还OK,不过这不是重点。
这回我要老老实实讨论一下这类题目的解答方法。一开始拿到这个题目就知道这肯定是一个关系到比特处理的题目。至于怎么处理,就需要我们细细思考了。之前有一道类似的题目,不过它的数组里面是重复的数字都出现了2遍,而这次是出现了3遍。
之前出现两遍的怎么解决呢?我们可以对每一个数组元素进行异或运算,对于重复出现的数字异或之后的结果肯定就是0了,而对于只出现了一次的数字,我们就可以得到它的反,对它再取一次反就可以得到他的结果辣。
但是现在我们却发现情况变成3次了,异或不好使了。。咋办。
这就像是我们要做一个机器,机器的输入是0或1,输出也是0或1,如果我么连续按三次一样的按钮,那么输出0,否则输出1。
所以顺着这个思路我们是不是可以这么写一个小机器:
#我是机器 def robot(input): n = 0 for i in input: if i == 1: n += 1 if n%3==0: return 0 else: return 1
说到这里,其实我们的目的已经达到了。
我们可以对数组的每一个元素放到机器中,每一个比特进行处理记录,最后得到的结果就是我们需要的数。
代码具体如下(来自互联网):
class Solution { public: int singleNumber(int A[], int n) { int count[32]={0}; int result=0; for(int i=0;i<32;i++){ for(int j=0;j<n;j++){ count[i]+=((A[j]>>i)&1); //首先把输入数字的第i位加起来。 count[i]=count[i]%3; //然后求它们除以3的余数。 } result|=(count[i]<<i);//把二进制表示的结果转化为十进制表示的结果 } return result; } };