码迷,mamicode.com
首页 > 其他好文 > 详细

【LeetCode】Single Number I & II

时间:2015-08-12 23:03:53      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

Single Number I :

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

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

 


 

Solution:

解法不少,贴一种:

1 class Solution:
2     # @param {integer[]} nums
3     # @return {integer}
4     def singleNumber(self, nums):
5         ans = nums[0];
6         for i in range(1, len(nums)):
7             ans ^= nums[i]
8         return ans

 

其依据在于:

1、异或运算满足交换律;

2、a ^ a = 0;

3、b ^ 0 = b。

 

这题的关键就在于线性时间内把相同的一对 “消掉”,留下那个 “落单” 的。

异或运算给了这样的快捷的可能。

 

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?

 


 

 

Solution:

同样,考虑用位运算解题:

在 I 中巧妙地用异或运算解决了把重复的元素的“消除”,只留下“落单”的元素的问题。而在 II 中,除了要找的元素,每个元素都出现 3 次,I 的解法适用于出现偶数次的情况,但对于奇数次已不再适用。

考虑每个数用二进制展开,将各个数横向比较:

对于一个32位(或者64位)的整数,对于这32个位中的某个位而言,如果每个数都出现三次,那么对于所有数在这个位上“1”的个数,一定是 3 的倍数;而反之,如果存在某个数不是出现 3 次(也不是 3 的倍数次,这是题目未讲明处,I 亦同理如此),那么对于它的二进制展开后数为 1 的位而言,对于所有数在这个位上“1”的个数,一定不是 3 的倍数。

所以具体的解决办法是:

用一个 32 长的数组存储对于所有数的二进制展开,每一个位上总共 “1” 的个数和,最后看那些位上 “1” 的个数不是 3 的倍数,那么这一位在 ans 中就是 1。

算法是 O(32n) 的。

 

有一点需要注意的是:

不同的语言中对位运算尤其是符号位的处理是不尽相同的,比如 C++ 中最高位是符号位,如果不是 3 的倍数那么最后的 ans 就是负数,符号位可以和其他位一样处理;但如果是Python,由于其动态类型的特性,当超出数据范围时,会自动转化为更大范围的数据类型,而不会将其作为符号位处理。

 

C++版本:

 1 class Solution {
 2 public:
 3     int singleNumber(int A[], int n) {
 4         int bitnum[32] = {0};
 5         int res=0;
 6         for(int i = 0; i < 32; i++){
 7             for(int j = 0; j < n; j++){
 8                 bitnum[i] += (A[j] >> i) & 1;
 9             }
10             res |= (bitnum[i] % 3) << i;
11         }
12         return res;
13     }
14 };

Python版本:

 1 class Solution:
 2     # @param {integer[]} nums
 3     # @return {integer}
 4     def singleNumber(self, nums):
 5         bitNum = [0] * 32
 6         for i in range(32):
 7             for e in nums:
 8                 bitNum[i] += (e >> i) & 1
 9         ans = 0
10         for i, val in enumerate(bitNum):
11             if i == 31 and val % 3 != 0:
12                 ans = -((1 << i) - ans)
13             else:
14                 ans |= (val % 3) << i
15         return ans

其中对于逻辑上的符号位(第32位),单独判断并处理,如果为 1,则需要转化为对应的负数(对应的负数的绝对值 = 【模】- 不考虑符号位(符号位为0)的正数)。

 

【LeetCode】Single Number I & II

标签:

原文地址:http://www.cnblogs.com/maples7/p/4483196.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!