LeetCode-137. 只出现一次的数字 II

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

1.题目描述

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 **三次 。**请你找出并返回那个只出现了一次的元素。

示例 1:

输入:nums = [2,2,3,2]
输出:3
复制代码

示例 2:

输入:nums = [0,1,0,1,0,1,99]
输出:99
复制代码

提示:

  • 1 <= nums.length <= 3 * 104
  • -231 <= nums[i] <= 231 - 1
  • nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次

Tips: 力扣地址:leetcode-cn.com/problems/si…

2. 思路分析

方式1:整个最容易想到的方法解决就是通过额外空间,定义一个HashMap,key为元素,value为元素出现的次数。这个是实现最容易想到的解决方案,遍历整个数组然后将数组的次数统计出来到map的value中。AC代码如下代码1。

方式2:上面的方法是最简单的最容易想到的,那么有没有比较巧妙的方法。都知道int的类型是32位我们用额外创建一个int[]数组a长度为32。用长度来模拟int的位数,int[i]的值表示该位上面的1的次数。相同的数据位上的数据是相同的。然后将用a[i]%3 & 1 与是否等于1来判断。如果等于1表示这个位上的1属于只出现一次的元素。AC代码如下代码2.

3. AC代码

代码1:

class Solution {
    public int singleNumber(int[] nums) {
TreeMap<Integer,Integer> data = new TreeMap<>();
        Arrays.stream(nums).forEach(item-> data.put(item, data.getOrDefault(item, 0)+1));
        Set<Map.Entry<Integer, Integer>> entries = data.entrySet();
        for(Map.Entry<Integer, Integer> item : entries){
           if( item.getValue() == 1){
               return item.getKey();
           }
        }
        return 0;
    }
}
复制代码

代码2:

class Solution {

public int singleNumber(int[] nums) {
        int[] cnt = new int[32];
        for (int x : nums) {
            for (int i = 0; i < 32; i++) {
                if (((x >> i) & 1) == 1) {
                    cnt[i]++;
                }
            }
        }
        int ans = 0;
        for (int i = 0; i < 32; i++) {
            if ((cnt[i] % 3 & 1) == 1) {
                ans += (1 << i);
            }
        }
        return ans;
    }
    
}
复制代码

4. 总结

方式1是最容易想到也最简单的,方式2就是巧妙的利用位和数组进行转换。巧妙求解

扫描二维码关注公众号,回复: 13751615 查看本文章

我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢

猜你喜欢

转载自juejin.im/post/7080050663660617764
今日推荐