zoukankan      html  css  js  c++  java
  • 数组中只出现一次的数字

    题目1-LeetCode136

    先来看一道LeetCode的相似题目,给定一个数组,数组中只有一个数字出现了一次,其余数字都出现了两次,找出出现一次的数字,返回结果。

    提示

    算法不能使用额外的空间,且时间复杂度是O(1)。

    解法

    采用异或运算符,^ 相同位为0,不同位是1.所以两个相同的数字进行异或操作,返回结果是0,因此这道题就很容易得出答案了。

    代码

    class Solution {
        public int singleNumber(int[] nums) {
            int res = 0;
            // 因为只有一个数字出现了一次,其余数字出现了两次,所以遍历数组所有元素进行异或,异或的结果就是出现了一次的数字。
            for(int i=0;i<nums.length;i++){
                res ^= nums[i];
            }
            return res;
        }
    }
    

    牛客剑指Offer

    题目

    一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

    分析

    这道题与上一道题不同之处在于有两个数字出现了一次,其余数字出现了两次,也可以采用异或操作,我们设最后的两个结果一个是a一个是b,异或到最后是n=a^b。
    那怎样才能把它分开呢?
    我们可以找出n他的二进制中从右往左数第一次出现1的位,然后根据数组元素的这一位是不是也是1,将数组一分为二,变成两个子数组;因为相同的数字肯定分到同一个子数组中,不同的肯定不在同一个子数组中,所以,a和b不在一个子数组中。最终将两个子数组异或,得到的结果就是a和b。

    代码

    //num1,num2分别为长度为1的数组。传出参数
    //将num1[0],num2[0]设置为返回结果
    public class Solution {
        public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
            int n= 0 ;
            for(int i=0;i<array.length;i++){
                n^=array[i];
            }
            // 计算出res二进制中从右往左数第一个1
            int last = n-(n&(n-1));
            for(int j=0;j<array.length;j++){
                // 第一个子数组的第last位都不是1,两个不同的数肯定不会在同一个子数组中
                if((last&array[j])==0){
                    num1[0]^=array[j];
                }else{
                    //第二个子数组的last位都是1
                    num2[0]^=array[j];
                }
            }
        }
    }
    

    需要注意的是上面有个计算出n的二进制中从右往左第一次出现1的位置的公式last= n-(n&n-1);比如n=11100,n-1=11011;n&n-1=11000;n-(n&n-1)=100。

  • 相关阅读:
    Kubernetes 升级过程记录:从 1.17.0 升级至最新版 1.20.2
    歼10:职业有个基本属性,为了糊口。然后再区分 主动 or 被动,被动者只是为了糊口,那自然是看不起自己的职业
    红胖子:写给人生的九封信,愿你的人生淡定从容,繁华似锦!!!
    Embarcadero MVP(68位,全部都有个人主页)
    Delphi 26 岁
    C# Assembly 与 Reflection
    你精通那么多技术,为何还是做不好一个项目
    Linux 6 个“吓人”的 命令
    Distributed Application runtime
    RocketMQ and kafka
  • 原文地址:https://www.cnblogs.com/dataoblogs/p/14121856.html
Copyright © 2011-2022 走看看