算法:数组中数字出现的次数


问题

  • 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

解决


//1、利用hashset的特性进行判断
class Solution {
    public int[] singleNumbers(int[] nums) {
         int len1=nums.length;
         if(len1==2) return nums;
         
        HashSet<Integer> set=new HashSet<Integer>();
        
        // for(int i=0;i<len1;i++){
        //     if(!set.contains(nums[i])){
        //         set.add(nums[i]);
        //     }else{
        //         set.remove(nums[i]);
        //     }
        // }
        int left=0,right=len1-1;
        while(left<=right){
           if(nums[left]==nums[right]){
               left++;
               right--;
               continue;
           }
           if(!set.contains(nums[left])){
               set.add(nums[left]);
           }else {
                set.remove(nums[left]);
           }
           if(!set.contains(nums[right])){
               set.add(nums[right]);
           }else{
                set.remove(nums[right]);
           }
           left++;
           right--;
        }


        int[] arr=new int[2];
        int a=0;
        for(int j:set){
            arr[a++]=j;
        }
        return arr;
    }
}


//2、通过异或操作获取值
class Solution {
    public int[] singleNumbers(int[] nums) {
        int ret = 0;
        for (int n : nums) {    //得到两个子出现1次的值的异或值:此时结果中的位上的1表示两数原本位置上是不同的值
            ret ^= n;
        }
        int div = 1;
        while ((div & ret) == 0) {      //提取出最右边的1
            div <<= 1;        //将1左移一位,=》0010。。。从而得到ret最右边的1     
        }
        int a = 0, b = 0;
        for (int n : nums) {        //能够将两个出现1次的分到不同的两组(因为他们在div对应得位置不同),相同的数分到一组(在div对于得位置上相同)!
            if ((div & n) != 0) {           //第一组
                a ^= n;
            } else {
                b ^= n;                     //第二组
            }
        }
        return new int[]{a, b};
    }
}


总结

算法:数组中数字出现的次数

  • 第二种方式更优

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/278982.html

(0)
上一篇 2022年8月5日
下一篇 2022年8月5日

相关推荐

发表回复

登录后才能评论