每天一道编程题

66 阅读2分钟

题目:LCR 004. 只出现一次的数字 II

给你一个整数数组 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则是题解方法。

方法1: 排序+顺序查找

1)因为每个元素出现的次数都是固定的,可以用排序+顺序查找,来找到只出现了一次的元素。

代码

class Solution {
    public int singleNumber(int[] nums) {
        int n=nums.length;
        if(n==1) return nums[0];
        Arrays.sort(nums);
        int i=0;
        while(i<n){
            if(i+2<n && nums[i]==nums[i+2]){
                i+=3;
            }else{
                return nums[i];
            }
            
        }
        return -1;

    }
}

方法2:哈希表

2)可以直接用HashMap来存储每个元素出现的次数,然后遍历value值找到只出现一次的key。

代码

class Solution {
    public int singleNumber(int[] nums) {
        Map<Integer,Integer> map=new HashMap<>();
        for(int n: nums){
            map.put(n,map.getOrDefault(n,0)+1);
        }
        for(Map.Entry<Integer,Integer> entry: map.entrySet()){
            int key=entry.getKey(), val=entry.getValue();
            if(val==1){
                return key;
            }
        }
       
        return -1;

    }
}

3)题中除答案外,每个元素只出现三次,对应元素的二进制位和应该都为3或是0。

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for (int i = 0; i < 32; i++) {
            int total = 0;
            for (int n : nums) {
                //获取n的第i个二进制位
                total += ((n >> i) & 1);
            }
            if (total % 3 != 0)
                ans |= (1 << i);
        }
        return ans;

    }
}