剑指 Offer 56 - II. 数组中数字出现的次数 II
在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例 1:
输入:nums = [3,4,3,3]
输出:4
示例 2:
输入:nums = [9,1,7,9,7,9,7]
输出:1
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
对比上一题,这题没有时间限制
核心:找规律,先进行排序,这时只有三种情况,数字在第一位时,数字在最后一位时,数字在中间时,三种情况进行判断输出即可,比如
ABBBCCC
BBBACCC
BBBCCCA
class Solution {
public int singleNumber(int[] nums) {
Arrays.sort(nums);
//不重复数字在头
if (nums[0]!=nums[1]){
return nums[0];
}
//不重复数字在尾
if (nums[nums.length-1]!=nums[nums.length-2]){
return nums[nums.length-1];
}
//不重复数字在中间,遍历判断
for (int i = 1; i < nums.length-1; i++) {
if (nums[i]!=nums[i-1]&&nums[i]!=nums[i+1]){
return nums[i];
}
}
return 0;
}
}
核心:位运算(同类问题万能解法),新建count数组将所有数字二进制的1出现次数存起来,再将所有每一位数字取余3(或其他重复次数),然后最后取余剩下的count数组即为不重复的数字的二进制
class Solution {
public int singleNumber(int[] nums) {
int[] count=new int[32];
for (int i = 0; i < nums.length; i++) {
//每一个数字的每一位二进制如果为1,count数组当前值++,最后获得count数组为所有数字的二进制1出现次数
for (int j = 0; j < 32; j++) {
count[j]+=nums[i]&1;
nums[i]=nums[i]>>>1;
}
}
int res=0;
for (int i = 0; i < 32; i++) {
res=res<<1;
//如果当前count数组值取余为1,那么数字的二进制值在该位为1,|=的意思是0|1=1,0|0=0,如果该位存在,则将res该位置1
res=res|(count[31-i]%3);
}
return res;
}
}
核心:哈希表记录结果,结果次数等于1的输出(效率较低)
class Solution {
public int singleNumber(int[] nums) {
Map<Integer,Integer> map = new HashMap<>();
int x=0;
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(nums[i])){
map.put(nums[i],map.get(nums[i])+1);
}else {
map.put(nums[i],1);
}
}
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
for (Map.Entry<Integer, Integer> entry : entries) {
if (entry.getValue()==1) {
x=entry.getKey();
break;
}
}
return x;
}
}