[数组]剑指 Offer 56 - I. 数组中数字出现的次数

题目:

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

 

示例 1:

输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:

输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
 

限制:

2 <= nums.length <= 10000

解答:

方法一:分组异或

时间复杂度:O(n)  空间复杂度:O(1)

将所有数字异或后得到的数字必为非零数(有两个数不相同)。根据得到的这个非零数,将数组分为两个子数组,每对相同的数必定在同一个数组中,而两个不同的数必定不再同一个数组中。再对每个子数组进行异或操作,最后得到的两个数就是这两个不同的数。

class Solution {
    public int[] singleNumbers(int[] nums) {
        int res[] = new int[2];
        
        int resXor = 0;
        for(int num:nums){
            resXor ^=num;
        }
        int indexBit1 = findFirstBit1(resXor);
        for(int num: nums){
            if(isBit1(num,indexBit1)){
                res[0] ^=num;
            }
            else{
                res[1] ^=num;
            }
        }

        return res;
    }

    public int findFirstBit1(int num){
        int indexBit1 = 0;
        while((num&1) == 0){
            ++indexBit1;
            num = num>>1;
        }
        return indexBit1;
    }

    public boolean isBit1(int num,int indexBit1){
        int tmp = num>>indexBit1;
        if((tmp&1) !=0) return true;
        else return false;
    }
}

 方法二:(哈希法)

代码:

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果

import java.util.HashMap;
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        //哈希算法
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int i=0; i < array.length; i++){
            if(map.containsKey(array[i]))
                map.put(array[i],2);
            else
                map.put(array[i],1);
        }
        int count = 0;
        for(int i=0; i < array.length; i++){
            if(map.get(array[i]) == 1){
                if(count == 0){
                    num1[0] =  array[i];
                    count++;
                }else
                    num2[0] =  array[i];
            }
        }

    }
}

 

posted @ 2020-07-13 11:22  3KBLACK  阅读(69)  评论(0)    收藏  举报