码农小汪剑指Offer之38-数组中只出现一次的数字 异或运算的运用

原创 2016年04月09日 23:02:51

题目描述

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

解题思路

这道题,看上去没啥的,其实真实的很难,如果你从未接触过,一般情况下多数都是无法搞定这个问题的,不好解决!如果可以使用HashMap那么还需要你来解决?

这道题考的是异或运算,而且增加了难度!
从题目可以知道,其他的数字都是有两个的,对吧!只有其中的两个数字不一样!两个数字不一样的话,异或肯定存在区别的。至于区别 在何处,我们慢慢的到来

a 异或 b
按位异或

a 为 5 — 0101
b 为 7 —-0111
____
0010
对应位相同为0, 不同为1
因为,有两个不同的数字,一定存在有一位不一样的,而且不一样的,位肯定为1,我们只要找到不一样的位置在哪里就晓得了。

还有个性质没有讲,两个相同的数字异或为0。那么我们首先将所有的数字异或之后。就剩下两个不同数字异或的结果。让后寻找不一样的位置就好了。这样就可以解决问题!
这样就造成了,在某一位上肯定会出现一个为0
一个为1。

if (array.length < 2) {
            return;
        }
        int result = 0;

        for (int i = 0; i < array.length; i++) {
            result ^= array[i];
        }

找到不同的位置

        int flag = 1;
        // 我们找到不一样的第一位
        int j = 1;
        while (true) {
            if ((result & j) == 1) {
                break;
            }
            result = result >> 1;//比较最低位是否为不同的那一位!
            flag = flag << 1;
        }

分为两个数字,因为flag&这两个不同的数字,一定可以区分出来,这两个数字,其他的任意来啦!随便他们放在哪边,总会出现为异或为0的结果,对于最后的值没有影响!

        num1[0] = 0;
        num2[0] = 0;
        for (int i = 0; i < array.length; i++) {
            if ((array[i] & flag) == 0) {
                num1[0] ^= array[i];
            } else {
                num2[0] ^= array[i];
            }
        }

完整代码:

package JianzhiOffer;

public class Slution37 {

    public static void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {

        if (array.length < 2) {
            return;
        }
        int result = 0;

        for (int i = 0; i < array.length; i++) {
            result ^= array[i];
        }
        int flag = 1;
        int j = 1;
        while (true) {
            if ((result & j) == 1) {
                break;
            }
            result = result >> 1;
            flag = flag << 1;
        }
        num1[0] = 0;
        num2[0] = 0;
        for (int i = 0; i < array.length; i++) {
            if ((array[i] & flag) == 0) {
                num1[0] ^= array[i];
            } else {
                num2[0] ^= array[i];
            }
        }
    }
}

http://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

版权声明:码农小汪,欢迎交流 QQ:983433479

相关文章推荐

码农小汪剑指Offer之36-二叉树的深度 层次遍历 分而冶之

题目描述输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。解题思路我已看到这个题目的时候,就想到了利用分冶的方法,利用递归的思路。...

剑指offer——数组中只出现一次的数字(好题,熟悉位运算)

题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 思路:...

剑指offer 38. 数字在排序数组中出现的次数

//题目:给出排序数组,给出一个数,返回这个数的出现次数 public class Main { public static void main(String[] args) throws Exc...

剑指offer 面试题38 数字在排序数组中出现的次数

剑指offer 面试题38 数字在排序数组中出现的次数 统计一个数字在排序数组中出现的次数。例如输入排序数组 {1,2,3,3,3,3,4,5} 和数字 3, 由于 3 在这个数组中出现了 ...

剑指offer38:数字在排序数组出现的次数

/** * Created by WHZ on 2017/4/7. */ public class offer38 { int getUpper(int arr[], int key){...

剑指offer-面试题38-数字在排序数组中出现的次数

package case38_NumbersOfK; /** * 题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次...

剑指 offer代码解析——面试题38数字在排序数组中出现的次数

题目:统计一个有序数组中K出现的次数。 分析:本题最直观的思路就是遍历数组,统计K出现的次数即可。 这种方式的时间复杂度为O(n)。下面我们充分利用“有序数组”这一条件,提高算法的时间效率...

【剑指offer】面试题38-数字在排序数组中出现的次数

问题描述:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3字数组中出现了4次,因此输出4.问题分析:方法1:利用二分查找的思想,找到中间数据是不是...

剑指Offer----面试题38:数字在排序数组中出现的次数

题目: 统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4。 方法一 从前向后一...

《剑指offer》:[38]数字在排序数组中出现的次数

“沟通、学习能力就是看面试者能否清晰、有条理地表达自己,是否会在自己所得到的信息不够的情况下主动发问澄清,能否在得到一些暗示之后迅速做出反应纠正错误”                         ...
  • gogoky
  • gogoky
  • 2016年06月19日 15:53
  • 1212
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:码农小汪剑指Offer之38-数组中只出现一次的数字 异或运算的运用
举报原因:
原因补充:

(最多只允许输入30个字)