leetcode中等剑指 Offer 56 数组中数字出现的次数

Posted qq_40707462

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode中等剑指 Offer 56 数组中数字出现的次数相关的知识,希望对你有一定的参考价值。

1、

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)

思路:位运算
相同的数异或为0,不同的异或为1。0和任何数异或等于这个数本身。

一个只出现一次的数字:
全员进行异或操作即可。对于两个操作数的每一位,相同结果为 0,不同结果为 1。成对出现的数字的所有位会两两抵消为 0,最终得到的结果就是那个出现了一次的数字。

两个只出现一次的数字:
全员异或得到这两个数 ab 异或的结果 x,将两个数字分别分在两组,再按只有一个数的操作进行
分组:x[i]=1 表示 ab 的第 i 位是不同的 ,根据任意一位不为 0 ,都可以划分开

class Solution 
    public int[] singleNumbers(int[] nums) 
        int res=0;
        for(int n:nums) res^=n;
        //从右向左 寻找第一位不为 0 的数
        int tmp=1;
        while((res & tmp)==0) tmp<<=1;
        //分组
        int a=0,b=0;
        for(int n:nums)
            if((tmp & n)==0) a^=n;
            else b^=n;
        
        return new int[]a,b;
    

2、

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

思路:
如果一个数字出现3次,它的二进制每一位也出现的3次。如果把所有的出现三次的数字的二进制表示的每一位都分别加起来,那么每一位都能被3整除。 如果某一位能被3整除,那么这一位对只出现一次的那个数的这一肯定为0。如果某一位不能被3整除,那么只出现一次的那个数字的该位置一定为1.

class Solution 
    public int singleNumber(int[] nums) 
        int[]k=new int[32];
        for(int num:nums)
            for(int i=0;i<32;i++)
                k[i]+=num & 1;
                num>>=1;
            
        
        int res=0;
        for(int i=31;i>=0;i--)
            res=res<<1;
            if(k[i]%3==1)
                res=res | 1;
            
        
        return res;
    

以上是关于leetcode中等剑指 Offer 56 数组中数字出现的次数的主要内容,如果未能解决你的问题,请参考以下文章

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

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

LeetCode(剑指 Offer)- 题集

剑指offer38(Java)-字符串的排列(中等)

LeetCode一个整型数组里除两个数字之外,其他数字都出现了两次,请找出这两个只出现一次的数字(剑指 Offer 56 - I. 数组中数字出现的次数) | 数组分组异或

⭐算法入门⭐《二叉树 - 二叉搜索树》中等01 —— LeetCode 剑指 Offer 33. 二叉搜索树的后序遍历序列