菜鸟笔记
提升您的技术认知

数组中只出现一次的数-ag真人游戏

  问题一:在一个整数数组中,除了一个数之外,其他的数出现的次数都是两次,求出现一次的数,要求时间复杂度尽可能的小。例如数组{1,2,2,3,3,6,6},出现一次的数是1.

  从题目的描述可以看出,数组中只有一个数字出现了一次,其他的数字都出现两次,联想到异或运算的特点:任何一个数字和自己做异或运算的结果都是0,任何数字和0运算的结果都是本身。根据上述特点,可以考虑从数组的第一个元素开始,逐个和后面的元素做异或操作,最后的计算结果就是要找的只出现一次的数。

  算法实现如下:  

public class main {
    public static void main(string[] args){
        int[] nums = new int[]{1,2,2,3,3,4,4,1,23};
        system.out.println(getnumappearsonce(nums));
    }
    public static int getnumappearsonce(int[] nums){
        if(nums == null || nums.length <= 2){
            throw new illegalargumentexception("nums size must bigger than 2");
        }
        int result = 0;
        for(int i=0;i){
            result ^= nums[i];
        }
        return result;
    }
}

  由于只需要遍历一遍数组就可以找到结果,因此上述算法的时间复杂度为o(n),其中n为数组的长度

发散思维:假如要求的数组里面有两个数出现的次数是1,其他出现的次数都是2,如何找出这两个数呢?

  根据上面问题一的思路,我们依然从头到位对数组做异或运算,得到的最终结果应该是两个不同数字做异或运算后的值。因为两个数字不相同,最终的结果也肯定不是0,切结果对应的二进制位中至少有一个为1,我们找到二进制位中第一个是1的位置,即为n,然后根据地n为是1还是0把数组分为两个子数组,第一个子数组中的每个数的二进制位的第n位都是1,另外一个是0,这样分完后,相同的数字肯定会被分到同一个子数组中,并且每个子数组中只包含一个只出现一次的数,根据问题一,我们可以很方便的求出两个只出现一次的数,实现如下:

public class main {
    public static void main(string[] args){
        int[] nums = new int[]{1,2,2,3,3,4,4,1,23,43};
        system.out.println(getnumsappearsonce(nums));
    }
    public static int getnumappearsonce(int[] nums){
        if(nums == null || nums.length <= 2){
            throw new illegalargumentexception("nums size must bigger than 2");
        }
        int result = 0;
        for(int i=0;i){
            result ^= nums[i];
        }
        return result;
    }
    public static list getnumsappearsonce(int[] nums){
        if(nums == null || nums.length <= 2){
            throw new illegalargumentexception("nums size must bigger than 2");
        }
        list result = new arraylist(2);
        int temp = getnumappearsonce(nums);
        int index = findfirstbitidone(temp);
        int num1 = 0,num2 = 0;
        for(int i=0;i){
            if(isbitone(nums[i],index)){
                num1 ^= nums[i];
            }else{
                num2 ^= nums[i];
            }
        }
        result.add(num1);
        result.add(num2);
        return result;
    }
    private static boolean isbitone(int num, int index) {
        num = num >> index;
        return (num & 1) == 1;
    }
    private static int findfirstbitidone(int temp) {
        int index = 0;
        while((temp & 1) == 0){
            temp =  temp >> 1;
            index  ;
        }
        return index;
    }
}

 

网站地图