您的位置:首页 > 编程语言 > Go语言

LeetCode - Single Number

2014-04-16 16:01 393 查看

1. Single Number

1.1 问题

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?

1.2 分析

寻找数组中唯一一个非重复元素,直观上的解法有:

1)排序:快排,随后遍历有序数组,寻找非重复元素。时间复杂度:O(nlogn),空间复杂度:O(1)。

2)哈希:对原有数组建立哈希表,建表时若插入的值已存在表中,则移出表中的该元素。遍历完整个数组后,哈希表中剩下的元素即为所求的非重复元素。时间复杂度:O(n),空间复杂度:O(n)。

根据题目的要求,排序不满足时间复杂度的要求,而哈希则不满足空间复杂度的要求。

考虑位运算中异或运算的一种特殊情况:
a ^ a = 0
a ^ 0 = a

以及异或运算的运算法则:

a ^ b = b ^ a
a ^ b ^ c = a ^ ( b ^ c)

异或运算中相同两个数异或结果为0,一个数异或0结果为该数本身,且异或运算满足交换律和结合律,因此,对于数组:a, a1, a1, a2, a2, ..., an, an,对所有元素进行异或运算:a ^ a1 ^ a1 ^ a2 ^ a2 ^ ... ^ an ^ an = a ^ (a1 ^ a1) ^ (a2 ^ a2) ^ ...^ (an ^ an) = a,即得到所求的非重复元素。

该算法的时间复杂度为:O(n),空间复杂度为:O(1)。

1.3 实现

public int singleNumber(int[] A) {
int singleNum = 0;
for (int a : A) {
singleNum ^= a;
}
return singleNum;
}

1.4 扩展

可以扩展到包含任意个重复偶数次的元素以及一个重复奇数次的元素的数组,求该重复奇数次的元素。该算法同样适用。

2. Single Number Ⅱ

2.1 问题

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?

2.2 分析

元素重复次数为偶数次时,可以使用异或运算的特殊情况以及其运算法则来求解,当重复次数均为奇数次时,该解法失效。

考虑数字序列:9, 9, 9, 15, 15, 15,二进制表示分别为:

1001
1001

1001

1111
1111
1111

发现有如下规律:数组中所有重复元素的二进制表示中,相同位上1的数量之和必定能被3整除。

因此,可以对数组中所有元素的二进制表示中,各个位上为1的数量分别进行求和,然后对3取余,剩下的数即为非重复元素。

2.3 实现

Int型数值一般为32位长,因此可用一个长度为32的数组对数组中所有元素各个位上为1的数进行求和。

其中,得到一个数a的第i位的值得方法为:a >> i & 1(>>的优先级高于&)

此外,由一个数的位的构成得到该数的方法为:for (int i = 0; i < 32; i++) { result |= 1 << i;}

算法的实现如下:

public int singleNumber(int[] A) {
final int INT_LENGTH = 32;
final int REPEAT = 3;

int[] bits = new int[INT_LENGTH];
int result = 0;

for (int i = 0; i < bits.length; i++) {
bits[i] = 0;

for (int j = 0; j < A.length; j++) {
bits[i] += A[j] >> i & 1;
}

if (bits[i] % REPEAT != 0) {
result |= 1 << i;
}
}

return result;
}


2.4 扩展

事实上,该方法可以扩展到任意个重复n次的数,以及一个重复m次的数(m % n != 0),求该重复m次的数的一般性情况,只需将REPEAT设为n即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息