数组中只出现一次的数字(java)

题目描述:

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

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        
    }
}

分析:

思路一:暴力解法
先排序,然后比较a[i]和a[i-1],a[i+1],如果都不相同则输出,注意边界情况的判断。

思路二:暴力解法
遍历一遍,用ArrayList存储已经出现了一次的数字,当该数字出现第二次时,把它从ArrayList中移除,最后剩下的就是只出现了一次的数字。(用ArrayList存储是因为,该数据结构方便插入和删除操作。)

思路三:位相与

  1. 除了有两个数字只出现了一次,其他数字都出现了两次。异或运算中,任何一个数字和自己本身异或都是0,任何一个数字和0异或都是本身。
  2. 如果尝试把原数组分成两个子数组,且刚好每个子数组中各自包含一个只出现一次的数字。则在该前提下,每个子数组中,只有一个数字出现了一次,其他数字都出现了两次。
  3. 针对每个子数组,从头到尾依次异或每个数字,则最后留下来的就是只出现了一次的数字。因为出现两次的都抵消掉了。
  4. 怎样实现子数组的划分呢。若对原数组从头到尾的进行异或,则最后得到的结果就是两个只出现一次的数字的异或运算结果。这个结果的二进制表示中,至少有一位为1,因为这两个数不相同。该位记为从最低位开始计数的第n位。
  5. 则分组的标准定为从最低位开始计数的第n位是否为1。因为出现两次的同一个数字,各个位数上都是相同的,所以一定被分到同一个子数组中,且每个子数组中只包含一个出现一次的数字。

& 是 按位与运算符
-x 是x 的补码;补码为取反+1
x&(-x)返回x与2^64 的最大公约数,即x最多能被n个2整除就返回2^n;
如果x是奇数返回1
所以:
返回值为0,表示x=0
返回值为1,表示x为奇数
返回值为其他数,表示x为x与2^64的最大公约数

解答:

思路二:暴力解法

import java.util.ArrayList;
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        ArrayList<Integer> once = new ArrayList<Integer>();
        for (int i = 0; i < array.length; i++) {
            int a = array[i];
            if(once.contains(a)){
                once.remove(once.indexOf(a));
            }else{
                once.add(a);
            }
        }
        num1[0] = once.get(0);
        num2[0] = once.get(1);
    }
}
运行成功

思路三:位相与

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int[] nums, int num1[], int num2[]) {
        int diff = 0;
        for (int num : nums)
            diff ^= num;
        // 得到最右一位
        diff &= -diff;
        for (int num : nums) {
            if ((num & diff) == 0)
                num1[0] ^= num;
            else
                num2[0] ^= num;
        }
    }
}
运行成功
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 9,689评论 0 13
  • 五年之后,我回到了这里,没有理想中的衣锦还乡,确意想不到的收获着。 特地让司机师傅在没到校门口之前停车,我如愿以偿...
    茴汐阅读 3,342评论 0 2
  • 踏莎行 晏殊 小径红稀,芳郊绿遍。高台树色阴阴见。春风不解禁杨花,濛濛乱扑行人面。 翠叶藏莺,朱帘隔燕。炉香静逐...
    顧勇詩書阅读 1,436评论 0 5
  • 最早开始书写大约不过是为了消遣烦闷,记得那时候刚失业,一个人待在家里心情十分低落,心中似有千言万语却无处可...
    夜雪_5e1b阅读 1,150评论 0 0
  • 抬头迈步向前行, 一刻不歇停。 不顾雨,不看风, 一路奔前程。
    李缓之阅读 2,312评论 4 20