Sword56-II——数组中数字出现的次数 II

博客围绕Sword56-II,即数组中数字出现的次数 II 问题展开。采用有限状态交换机方法,利用二进制特性,对所有数字二进制位上1的个数状态进行分析,通过定义 two、one 两个二进制位表示状态变化,经循环遍历数组求解 one 和 two,最终 one 即为出现一次的数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sword56-II——数组中数字出现的次数 II

注:五颗星困难模式,不喜勿入

方法1——有限状态交换机

  • 思路:二进制形式中,对于出现三次的数字,其对于1上的数一定可以被3整除,即为3的倍数,因此只需要其最后结果的每一位上都对3求余,最后剩下的各个位上为1的数字即为最后结果
    • 因为任何数字对3取余的余数有3种(0、1、2),因此所有数字的二进制上1的个数状态只可能有3种
    • 对于二进制该位上输入的情况
      • 若输入二进制中该位为0,则状态保持不变
      • 若输入二进制中该位为1,则状态变化有三种情况
        • 0 -> 1
        • 1 -> 2
        • 2 -> 0
    • 由于二进制中只有0、1的表示,因此表示三种情况需要由两个二进制位进行表示,即two、one。将上述情况转换即为
      • 若输入二进制中该位为0,则状态保持不变
      • 若输入二进制中该位为1,则状态变化有三种情况
        • 00 -> 01
        • 01 -> 10
        • 10 -> 00
    • 如何计算one?
      • 首先需要考虑two是否需要进位,其次需要考虑two的降位
      • 当two为0时
        • 输入为0,one不管从0或1,都将不变,即为one
        • 输入为1,one从0为1、从1为0,都将取反,即为~one
      • 当two为1时(此时one起始只能为0)
        • 输入为0或1,one都只能为0
      • 综上所述
        • 当two为0,one = one ^ n
        • 当two为1,one = 0
      • 再次简化:one = one ^ n & ~two
    • 如何计算two?(同one计算,只不过是在新one上计算)
      • 即最终结果为:two = two ^ n & ~two
  • 特殊情况与临界分析:无
  • 终止条件:无
  • 步骤:
    • 定义两个表示进制的数字
    • foreach循环遍历数组
      • 求解one
      • 求解two
    • 退出循环时,one即为出现一次的数字
    public int singleNumber(int[] nums) {
        // 定义表示进制的两个数字
        int one = 0, two = 0;
        // foreach循环
        for (int num : nums) {
            // 求解one
            one = one ^ num & ~two;
            // 求解two
            two = two ^ num & ~one;
        }
        // 返回出现一次的数字
        return one;
    }

方法1——有限状态交换机

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值