• 剑指offer56:数组中只出现一次的数字


    题目描述

    一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
     思路:对于这个题目是没有较好的思路的,只能想到遍历然后利用map计数的方法。
    看了书上的解释才学到了利用异或的方法进行计算
    Tips: 1. 两个相同的数异或值为0
       2. 如果数组中除一个数字外,其余数字都出现两次,那么所有数字的异或值结果即为只出现一次的数
       3. 题目中是存在两个只出现一次的数,那么所有数字的异或值就是这两个数字的异或值。
       4. 由于两个只出现一次的数的异或值肯定不为0,那么异或值的二进制的某一位一定为1,假设为第count位
       5. 接着把原数组分成两组,分组标准是第3位是否为1,那么两个只出现一次的数一定被分到两个不同的组
       6. 对两个组分别求异或值,即可求得两个只出现一次的数字
    代码实现:
    C++较繁琐的实现,注意这里int* num1,int* num2是指针传递,赋值的时候应*num1 = yihuo;
    class Solution {
    public:
        void FindNumsAppearOnce(vector<int> data,int* num1,int* num2) {
            int len = data.size();
            if(len == 0) return;
            //求数组所有数的异或值
            int result = data[0];
            for(int i=1;i<len;i++){
                result = result ^ data[i];
           }
            int count = 0;
            int temp = result;
            //求异或值第几位为1
            while(true){
                if(temp & 1 == 1)
                    break;
                temp = temp >> 1;
                count++;
            }
            //把数组分为两部分
            vector<int> newData;
            for(int i=0;i<len;i++){
                if((data[i]>>count) & 1 == 1)
                    newData.push_back(data[i]);
            }
            int yihuo = newData[0];
            for(int i=1;i<newData.size();i++){
                yihuo = yihuo ^ newData[i];
            }
            *num1 = yihuo;
            *num2 = (result ^ yihuo);
        }
    };

     精简后的代码(java):

    //num1,num2分别为长度为1的数组。传出参数
    //将num1[0],num2[0]设置为返回结果
    public class Solution {
        public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
            if(array.length == 0) return;
            //求所有结果的异或值
            int res = 0;
            for(int elem:array){
                res ^= elem;
            }
            //求该异或值从右边数第一个1的位数
            int num = 1;
            int indexOne = 0;
            while((res & num) == 0){
                num  <<= 1;
                indexOne++;
            }
            num1[0] = 0;
            for(int elem:array){
                if(((elem >> indexOne)&1)==1)
                    num1[0] ^= elem;
            }
            num2[0] = num1[0] ^ res;
        }
    }
  • 相关阅读:
    CUP的MESI协议
    synchronized 锁的升级
    BigDecimal/Long 前后端交互失去精度解决办法
    nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
    根据文件原始名称,文件根路径按照日期生成存储路径
    异步处理MultipartFile -- No such file or directory
    select下拉框相关操作(更新中。。。)
    input清空和重置select下拉框
    sql多字段分组排序显示全部数据
    ajax发送请求下载字节流形式的excel文件
  • 原文地址:https://www.cnblogs.com/ttzz/p/13862320.html
Copyright © 2020-2023  润新知