Single Number
XOR features:
a ^ b = c
a ^ c = b
b ^ c = a
a ^ 0 = a
a ^ a = 0
(a ^ b) ^ c = a ^ (b ^ c)
- I: all the numbers appear twice except one
XOR all the numbers, and the result is the one - II: all the numbers appear three times except one
Use aint[32]
to store each bit, if the number of this bit can be mod by 3, we set it as 0, otherwise we set it as 1. - III: all the numbers appear twice except two
XOR all the numbers so we can get thetwo
by XOR. Since these two elements are not the same, there is at least one bit that different. We find thisdifferent
position and XOR all the elements which have 1 on positiondifferent
, the result is one of the two. Finally, we XOR the found one with XOR-edtwo
, we can get another one.
Majority Number
- I: find the number appears more than half
Since it is a strict majority number, we only need to maintain a variableresult
and acounter
. Initially, when thecounter
faces with a different number, minus one of counter and change theresult
to this new number, otherwise we only need to add 1 to thecounter
. And finally, theresult
we maintained is the result. (We need to do another pass to make sure this number is the one we are looking for) - II: find the number appears more than 1/3
Similar with I, we maintain two variables and two counters so that we can get most appeared two numbers. And then we put these two numbers back to the array to find out which one appears more than 1/3. (We can’t use counter to find out, because counters have minus operation during the traversal) - III: find the number appears more than 1/k
We maintain aHashMap<number, counter>
. Since if majority, each k different numbers should have more than one element. When we get k entries in the map, we remove entries which values are 1. Finally, find the entry that have highest value(count), that key should be the majority number. In this way, we can implement this inO(n)
time andO(k)
extra space.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43public class Solution {
public int majorityNumber(ArrayList<Integer> nums, int k) {
if(nums == null || nums.size() == 0) {
return -1;
}
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int num : nums) {
if(map.containsKey(num)) {
map.put(num, map.get(num) + 1);
} else {
// if there are k entries, check if there are any entries that
// its value == 1, that is not satisfied with "more than 1/k"
if(map.size() == k) {
Iterator<Map.Entry<Integer, Integer>> iter = map.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry<Integer, Integer> entry = iter.next();
if(entry.getValue() - 1 == 0) {
// can't use: map.remove(entry.getKey());
// above wrong code would lead the iter can't find its next !!!
iter.remove();
} else {
map.put(entry.getKey(), entry.getValue() - 1);
}
}
} else {
map.put(num, 1);
}
}
}
// find the one that have highest value(count), that key should be the majority number
int value = 0;
int result = -1;
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
if(entry.getValue() > value) {
value = entry.getValue();
result = entry.getKey();
}
}
return result;
}
}