LeetCode琅琊榜第二十一层-只出现一次的数字

LeetCode琅琊榜第二十一层-只出现一次的数字(二进制算法)

题目

题目浏览

在这里插入图片描述

关键信息提取

  • 除了某一个元素仅出现过一次之外,其他都出现三次
  • 2e-31 <= nums[i] <= 2e31 - 1
  • 算法的时间复杂度应该是线性

题目信息解读

  • 在数组中,只可能出现两个情况
    • 某一个元素出想过三次
    • 某一个元素出想过一次
  • 每一个元素的取值范围都在一个int范围内

算法概述

哈希计数法

  • 哈希计数法主要有两种
    • 通过HashSet集合来计数,一般该集合处理的是出想过多次的元素
    • 通过HashMap集合来计数,一般该集合处理的是只出现过一次的元素
    • 很明显,这里采用的是**HashMap**集合来计数

二进制求解法

算法详解

算法思想

哈希计数法
  • 我们先遍历一次nums数组,通过一个HashMap来记录每一个元素出现的个数
  • 再遍历一次HashMap,找到只出现过一次的元素
二进制求解法

在这里插入图片描述

解析
  1. 该算法的突破口是我们的二进制位,因此我们先得到其每一个元素的二进制位,并将其位置对正
  2. 针对于出现过三次的元素,他们的二进制位一定是一样的,即对应的二进制位上会出现以下两种情况
    1. 1 + 1 + 1 = 3 % 3 = 0
    2. 0 + 0 + 0 = 0 % 3 = 0
  3. 不论是哪一种情况都是3的倍数,同理推理到所有出现过三次的元素,只要该元素出现过三次对应的二进制位上%3一定会等于0
  4. 如果最后求出来的结果(res = sum % 3) != 0, 说明,这个res一定是出现一次的二进制位,将这些二进制位记录下来即可获取出现过一次的数字

代码实现与分析

哈希计数法

class Solution {
    public int singleNumber(int[] nums) {
        var map = new HashMap<Integer,Integer>();
        var target = 0;
        for (var num : nums) {
            // 如果该元素不存在,就赋值为0+1,否则是原来的大小+1
            map.put(num,map.getOrDefault(num,0) + 1);
        }
        for (var res : map.entrySet()) {
            if (res.getValue() == 1) {
                target = res.getKey();
                break;
            }
        }
        return target;
    }
}

二进制求解法

class Solution {
    public int singleNumber(int[] nums) {
        // target 用于记录最终的结果
        var target = 0;
        // 每一个元素都在int范围内,所以一共有32个bit位,循环32次
        for (int i = 0; i < 32; i++) {
            // 记录每一个二进制位的和
            var sum = 0;
            for (var num : nums) {
                // 获取每一个二进制位的和,详情请看解析1
                sum += (num >> i) & 1;
            }
            // 详情请看解析2 
            if (sum % 3 != 0) {
                target |= (1 << i);
            }
        }
        // 返回结果即可
        return target;
    }
}

解析1

  1. 当我们想获取某一个二进制位的时候最简单的方法就是移位操作符 >> 或 <<,第一次移动i = 0位,第二次移动i = 1位,正好把 第一个和第二个二进制位取到,后面同理
  2. 在这个基础上,我们需要对结果&1,可以把前面可能有1的二进制位去掉,只留对应的那一位
  3. 叠加即可

解析2

  1. 出现过一次的元素的二进制情况也只能有两个,即0和1
    1. 如果是0,结果sum % 3 == 0成立,这个二进制位默认是0,不需要改变
    2. 如果是1,结果sum % 3 == 0不成立,这个二进制位默认是0,需要改变成1,所以最终只要改变是1的情况
  2. 1<<i就可以得到对应的二进制位

算法结论

二进制求解法是优于哈希计数法的,不信你可以验证一下

二进制求解法不仅可以用于本题,还能运用于力扣二十层中!

  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爪哇土著、JOElib

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值