ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法面试题-奇数次的数

2021-10-31 20:02:46  阅读:205  来源: 互联网

标签:curNum 面试题 int 假设 arr eor 算法 数次 dot


题目:

(1)一组数中,只有一个数出现了奇数次,其余数都出现偶数次,在O(N)的时间复杂度中找出该数
(2)一组数中,有两个数出现了奇数次,其余数都出现偶数次,在O(N)的时间复杂度中找出这两个数

分析:

(1)假设eor = 0,将eor分别与该数组中的全部数进行异或,最后得到的结果就是该数。比如数组为[2,1,3,1,2], eor = 0 ^ 2 ^ 1 ^ 3 ^ 1 ^ 2 = 1 ^ 1 ^ 2 ^ 2 ^ 3 = 0 ^ 0 ^ 3 = 3
(2)假设eor = 0,将eor分别与该数组中的全部数进行异或,最后得到的结果为a^b(假设这两个数为出现奇数次的数)。此时的eor肯定有至少有一个二进位是1(因为a不等于b),假设是第8个二进制位为1, 可以将所有数分为第8位为1和为0的, a和b肯定分别属于这两个类。假设eor’= 0, 将eor’和第8位为1的数分别去异或, 出现偶数次的数依旧不会干扰结果, 最后得到的eor’=a(如果a的第8位是1)。再将eor ^ eor’ = a^b^a = b, 此时a和b都求到了

代码实现:

public static void printOddTimesNum2(int[] arr) {
        /**
         * 题2
         */
        int eor = 0, eor_dot = 0;
        for (int curNum : arr) {
            eor ^= curNum;
        }
        // eor = a ^ b  eor != 0 eor二进制位上必有一个是1
        int rightOne = eor & (~eor + 1);  // *取出eor最右边的1, 假设eor=1011, ~eor=0100, ~eor+1=0101, eor & (~eor + 1) = 0001

        for (int curNum : arr) {
            if ((curNum & rightOne) == 1) { //将eor_dot和在rightOne位置上为1的数进行异或
                eor_dot ^= curNum;
            }
        }
        System.out.println(eor_dot + " " + (eor ^ eor_dot));
    }

public static void printOddTimesNum1(int[] arr) {
	    /**
	     * 题1
	     */
	    int eor = 0;
	    for (int cur : arr) {
	        eor ^= cur;
	    }
	    System.out.println(eor);
}

tips:

要取出eor二进制最右边的1, 可以采用以下代码实现。假设eor=1011,~eor=0100, ~eor+1=0101, eor & (~eor + 1) = 0001

int rightOne = eor & (~eor + 1)

标签:curNum,面试题,int,假设,arr,eor,算法,数次,dot
来源: https://blog.csdn.net/qq_41398418/article/details/121068867

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有