剑指 Offer 56 - II. 数组中数字出现的次数 II

这篇博客介绍了两种方法来解决数组中只有一个数字出现一次,其他数字都出现三次的问题。第一种方法是通过排序,检查首位和末位,以及中间的元素来找出不重复的数字。第二种方法利用位运算,创建一个count数组记录每个数字的二进制1的出现次数,然后对每个数除以3取余,根据count数组得出不重复的数字。还提到了使用哈希表记录出现次数,当次数等于1时输出该数字。这些方法都适用于无时间限制的情况。
摘要由CSDN通过智能技术生成

剑指 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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值