已知 arr 中只有 1 个数出现一次,其他的数都出现 k 次。
请返回只出现了 1 次的数。
数据范围: , ,
进阶:时间复杂度 ,空间复杂度
public int foundOnceNumber (int[] arr, int k) { // write code here int[] binary=new int[32]; for(int i=0;i<binary.length;i++){ int sum=0; for(int num:arr){ sum+=(num>>i)&1; //计算数据每个二进制位的1的加和 } binary[i]=sum; } int res=0; for(int i=0;i<binary.length;i++){ if(binary[i]%k!=0){ // 如果不能整除k,该位存在单数的二进制1,所有1左移加和 res+=(1<<i); } } return res; }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param arr int一维数组 * @param k int * @return int */ public int foundOnceNumber (int[] arr, int k) { // write code here int i; Arrays.sort(arr); for(i=0;i<arr.length-1;i++){ if(arr[i]!=arr[i+1]){ return arr[i]; } else{ i+=k-1; } } return arr[i]; } }
public int foundOnceNumber (int[] arr, int k) { // write code here //所有int型数字bit位之和 int[] binSum = new int[32]; for (int i = 0; i < arr.length; i++) { int num = arr[i]; for (int j = 0; j < 32; j++) { binSum[j] += ((num >> j) & 1); } } int ans = 0; //binSum[i] % k 得到出现一次数在第i bit位的值 for (int i = 0; i < 32; i++) { ans += ((binSum[i] % k) << i); } return ans; }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param arr int一维数组 * @param k int * @return int */ public int foundOnceNumber (int[] arr, int k) { // write code here if(k % 2 == 0){ return find(arr); } // 奇偶k都可以解决 // 因为其他的数都出现了k次 意味着在某一位二进制的位上的1/0出现了 nk 次 // 在考虑只出现一次的答案 他在这个位置的 0 1会叠加上去 // 以下只考虑某位1的数目(0的也是如此) // 非答案的某一位 1的个数 必然是 nk // 加上答案的某一位 1的个数 就是 nk + 1 或者 nk(答案此位为 0) // 可以发现答案的某一位是0还是1 等于 某一位1的个数取模k // 因此我们可以遍历统计每一位上的1的个数 然后取模获得 最终结果的某位 int res = 0; for(int i = 0; i < 32; i++){ int total = 0; for(int num : arr){ total += (num >> i) & 1; } res |= (total % k ) << i; } return res; } private int find(int[] nums){ int res = 0; for(int num:nums){ res ^= num; } return res; } }
public class Solution { public int foundOnceNumber (int[] arr, int k) { int ans = 0; for(int i = 0; i < 32; i++){ int sum = 0; for(int j = 0; j < arr.length; j++){ sum += (arr[j] >> i) & 1; } ans |= (sum % k) << i; } return ans; } }
import java.util.*; public class Solution { public int foundOnceNumber (int[] arr, int k) { HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); for(int i = 0;i<arr.length;i++) { if (map.containsKey(arr[i])) { map.put(arr[i], map.get(arr[i]) + 1); } else { map.put(arr[i], 1); } } for(Map.Entry<Integer, Integer> entry:map.entrySet()) { if (entry.getValue() == 1) { return entry.getKey(); } } return -1; } }
public int foundOnceNumber (int[] arr, int k) { HashMap<Integer, Integer> map = new HashMap<>(); for(int i = 0; i < arr.length; i++) { map.put(arr[i], map.getOrDefault(arr[i], 0) + 1); } Iterator it = map.keySet().iterator(); while (it.hasNext()) { int key = (Integer)it.next(); if (map.get(key) == 1) { return key; } } return -1; }
import java.util.*; public class Solution { public int foundOnceNumber (int[] arr, int k) { int[] countArr = new int [32]; for(int num : arr){ for(int i=0;i<32;i++){ //32位int整型,计算每个位置上1的个数 countArr[i] += (num>>(31-i))&1; } } int result = 0; for(int i=0;i<32;i++){ //出现K次的数对应位置1的个数是K的倍数,否则就是目标数字 result = (result<<1) + countArr[i]%k; } return result; } }
for(Map.Entry<Integer,Integer> entry:hashmap.entrySet()){ if(entry.getValue()==1) return entry.getKey(); }
public int foundOnceNumber (int[] arr, int k) { int ans = 0; for(int i = 0; i < 32; i++){ int sum = 0; for(int a : arr){ sum += (a >> i) & 1; } sum %= k; ans += (sum << i); } return ans; }
对数组进行排序,连续出现的数字放在一起,控制i,发现相同的数字出现,挑过K个数字,再比较。
public int foundOnceNumber (int[] arr, int k) {
Arrays.sort(arr);
int i=0;
while(i<arr.length){
if(i==arr.length-1) return arr[i];
if(arr[i]==arr[i+1]){
i=i+k;
}
else{
return arr[i];
}
}
return 0;
}
//方法一:利用Map集合 /* Map<Integer,Integer> map = new HashMap<>(); for (int i = 0; i < arr.length; i++) { if (!map.containsKey(arr[i])) map.put(arr[i],1); else map.put(arr[i],map.get(arr[i]) + 1); } int res = 0; for (int key : map.keySet()){ if (map.get(key) == 1){ res = key; } } return res; */ //方法二:同时利用List、Set两个集合 /* List<Integer> list = new ArrayList<>(); Set<Integer> set = new HashSet<>(); for (int i = 0; i < arr.length; i++) { if (!list.contains(arr[i])) { list.add(arr[i]); set.add(arr[i]); } else set.remove(arr[i]); } int res = 0; for (int ele : set){ res = ele; } return res; */ //方法三:利用数组 ///* Arrays.sort(arr); for (int i = 1; i < arr.length - 1; i++) { if (arr[i] != arr[i - 1] && arr[i] != arr[i + 1]) return arr[i]; } if (arr[0] != arr[1]) return arr[0]; else return arr[arr.length - 1]; //*/ //方法四:两层暴力for循环(思路上可行,但时间复杂度o(n^2),可能运行超时) /* for (int i = 0; i < arr.length; i++) { int count = 0; for (int j = 0; j < arr.length; j++) { if (arr[i] == arr[j]) count++; } if (count == 1) return arr[i]; } return -1; */
public int foundOnceNumber (int[] arr, int k) { // write code here Map<Integer,Integer> cache = new HashMap<>(); for(int a : arr){ int cnt = cache.getOrDefault(a,0) + 1; cache.put(a,cnt); } for(Map.Entry<Integer,Integer> entry : cache.entrySet()){ if(entry.getValue() == 1){ return entry.getKey(); } } return -1; }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param arr int一维数组 * @param k int * @return int */ public int foundOnceNumber (int[] arr, int k) { for(int i=0;i<arr.length;i++){ int count=0; for(int j=0;j<arr.length;j++){ if(arr[i]==arr[j]){ count++; } } if(count==1){ return arr[i]; } } return -1; } }
public int foundOnceNumber (int[] arr, int k) { // write code here //这个k其实没用额 //先排序 Arrays.sort(arr); //目标值 int target = arr[0]; //出现次数 int t = 0; for(int x=0; x < arr.length; x++) { //如果相等,次数相加,继续下次循环 if(arr[x] == target) { t ++; continue; } //如果不相等,则已经找完相等的数了,如果只有一,那我们就已经找到了 if(arr[x] != target && t == 1) { return target; } //如果不相等,且上个数的次数大于1,则不是我们要的,跳过,赋值为当前值 if(arr[x] != target && t > 1) { target = arr[x]; t = 1; } } return target; }