这两道题差不多,一个INT数组里除了一个INT出现1次,其他出现2(3)次。
虽然都AC了但是没有满足题目不使用额外空间的要求,还需改进。
思路是用hashmap记录每个INT出现的次数,如果到达2(3)次则删去,
最后MAP只剩下一个KV对则为所求。
public int singleNumber(int[] A) {
HashMap<Integer,Integer> m = new HashMap<Integer, Integer>();
int num = A.length;
for (int i = 0; i < num; i++) {
if(m.containsKey(A[i])) m.remove(A[i]);
else m.put(A[i],1);
}
for (int i = 0; i <num ; i++) {
if(m.containsKey(A[i]))return A[i];
}
return 0;
}
public int singleNumber(int[] A) {
HashMap<Integer,Integer> m = new HashMap<Integer, Integer>();
int num = A.length;
for (int i = 0; i < num; i++) {
if(m.containsKey(A[i])) {
if(m.get(A[i])==2)m.remove(A[i]);
else{
m.put(A[i],m.get(A[i])+1);
}
}else m.put(A[i],1);
}
for (int i = 0; i <num ; i++) {
if(m.containsKey(A[i]))return A[i];
}
return 0;
}
Update 2015/08/17: 上述做法虽然易理解但是空间复杂度较高,不如空间复杂度为1的位运算方法,对于1,可以将数组中的全部元素异或,这样最终的结果即为只出现了一次的元素,对于2来说,只要将全部元素按位相加,这样每位的数值即为a*3+b。由于a和b的取值范围为0或者1,这样只出现一次的数在每位的值即为x%3
public class Solution {
/**
*@param A : an integer array
*return : a integer
*/
public int singleNumber(int[] A) {
if (A.length == 0) {
return 0;
}
int n = A[0];
for(int i = 1; i < A.length; i++) {
n = n ^ A[i];
}
return n;
}
}
public class Solution {
/**
* @param A : An integer array
* @return : An integer
*/
public int singleNumberII(int[] A) {
// write your code here
if (A.length <= 0 ){
return 0;
}
if (A.length == 1){
return A[0];
}
int[] tmp = new int[32];
for (int i = 0; i < 32; i++){
for (int j = 0; j < A.length; j++){
tmp[i] += (A[j] >> i) & 1;
}
}
int res = 0;
for (int i = 0; i < 32; i++){
res += (tmp[i] % 3) << i;
}
return res;
}
}