只出现一次的数字

题目描述

给你一个整数数组nums,除某个元素仅出现一次外,其余每个元素都恰出现三次。请你找出并返回那个只出现了一次的元素。
示例 1:
输入:nums = [2,2,3,2]
输出:3

示例 2:
输入:nums = [0,1,0,1,0,1,100]
输出:100
 
提示:
1 <= nums.length <= 3 * 10^4
-2^31 <= nums[i] <= 2^31 - 1
nums 中,除某个元素仅出现一次外,其余每个元素都恰出现三次

思路一:暴力求解
对数组直接排序,如果相邻两个相等,就让下标走3步,不相等直接返回,遍历结束如果还没返回,说明是最后一个元素,直接返回最后一个元素

public int singleNumber1(int[] nums) {
    Arrays.sort(nums);
    int res = 0;
    for (int i = 0; i < nums.length - 1; ) {
        if (nums[i] == nums[i + 1]) {
            res = nums[i];
            i += 3;
        } else {
            return nums[i];
        }
    }
    return nums[nums.length - 1];
}

思路二:利用map,统计每个数字出现次数,最后在遍历输出出现一次的数

public int singleNumber2(int[] nums) {
    Map<Integer, Integer> mp = new HashMap<>();
    for (int i : nums) {
        mp.put(i, mp.getOrDefault(i, 0) + 1);
    }
        
    for (Map.Entry<Integer, Integer> e : mp.entrySet()) {
        if (e.getValue() == 1) {
            return e.getKey();
        }
    }
    return -1;    
}

思路三:位运算。数组中出现的数字都是3次,只有一个出现一次,所以把数组中的每位的数mod3剩下的就是出现一次的数字。每位找到之后按位放到返回值中即可。

public int singleNumber(int[] nums) {
    int tmp = 0;
    int res = 0;
    for (int i = 0; i < 32; i++) {
        for (int j : nums) {
            // 统计一趟每个二进制位之和
            tmp += (j >> i) & 1;
        }
        if (tmp % 3 != 0) {
            // 异或操作:就是将二进制位按原来数字二进制复位
            res |= (1 << i);
        }
        tmp = 0;
    }
    return res;
}
posted @ 2022-11-21 19:51  码到成功hy  阅读(33)  评论(0编辑  收藏  举报
获取

hahah

name age option