2048. 下一个更大的数值平衡数

数值平衡数 —— 找到严格大于 n 的最小数值平衡数

题目描述

给定一个整数 n,找出严格大于 n的最小“数值平衡数”。

数值平衡数定义如下:

一个整数 x 是数值平衡数,当且仅当对它的每一个数字 d,数字 d 在 x 中出现了恰好 d 次。

换句话说:

  • 统计 x 中每个数字出现的次数;
  • 若每个数字 d 出现次数等于 d,则 x 是数值平衡数。

举例:

  • 22 是数值平衡数,因为数字 2 出现了两次;
  • 1333 是数值平衡数,因为数字 1 出现一次,数字 3 出现三次;
  • 1022 不是数值平衡数,因为数字 0 出现了 1 次,但 0 只能出现 0 次(不能出现)。

示例说明

示例 1:

输入:n = 1
输出:22
说明:22 是最小的严格大于 1 的数值平衡数。


示例 2:

输入:n = 1000
输出:1333
说明:

  • 数字 1 出现 1 次
  • 数字 3 出现 3 次
    符合数值平衡数定义,且是严格大于 1000 的最小数值平衡数。

示例 3:

输入:n = 3000
输出:3133
说明:

  • 数字 1 出现 1 次
  • 数字 3 出现 3 次
    是严格大于 3000 的最小数值平衡数。

解题分析

题目难点

  • 数值平衡数的定义比较特殊,数字的出现次数直接等于数字本身;
  • 需要找出严格大于给定数字 n 的最小数值平衡数;
  • 需要排除数字 0 的出现(0 出现次数只能是0,不能出现);
  • n 最大可达到 10^6,搜索空间不是特别大,但暴力搜索可能效率一般。

观察与思考

  1. 数值平衡数的特性
    • 所有出现的数字 d,必须出现 d 次;
    • 数字 0 不能出现;
    • 数值平衡数中的数字种类和个数高度限制了数字本身的结构。
  2. 搜索策略
    • 可以从 n+1 开始,逐个判断是否是数值平衡数,找到第一个符合条件的数;
    • 判断方法是统计数字频率,验证频率和数字是否一致。
  3. 优化考虑
    • 由于符合条件的数值平衡数是有限的,可以考虑预先生成所有可能的数值平衡数列表;
    • 从预生成的列表中直接找到第一个大于 n 的数。

解题方法

方法一:暴力逐个检查

核心步骤:

  • n+1 开始依次递增;
  • 判断当前数是否是数值平衡数;
  • 判断方法:
    • 统计数字出现频率;
    • 若出现数字 0,则直接排除;
    • 对所有数字 d,判断其出现频率是否等于 d;
  • 找到符合的第一个数即返回。

代码示例:

class Solution:
    def nextBeautifulNumber(self, n: int) -> int:
        from collections import Counter

        def is_balanced(x: int) -> bool:
            s = str(x)
            count = Counter(s)
            if '0' in count:
                return False
            for digit, freq in count.items():
                if freq != int(digit):
                    return False
            return True

        x = n + 1
        while True:
            if is_balanced(x):
                return x
            x += 1

方法二:预生成所有数值平衡数

数值平衡数的数字只可能是 1 到 9(0不出现),且每个数字 d 必须出现 d 次。
这限制了数值平衡数的长度和结构:

  • 比如 22 长度为 2,只有数字 2,出现2次;
  • 1333 长度为 4,数字 1 出现1次,数字 3 出现3次;
  • 其他组合可能有限。

因此我们可以:

  • 用回溯或组合方式生成所有符合条件的数值平衡数;
  • 将它们存到列表中,排序;
  • 输入 n 时,快速查找列表中第一个严格大于 n 的数值平衡数。

这种方法在实际竞赛中更高效。


性能分析与比较

方法优点缺点适用场景
逐个检查法简单直观,代码实现容易大数值时效率较低n 较小,测试用例简单
预生成列表法查询速度快,性能优良需要提前生成列表,代码复杂度高多次查询或大范围

实际示例演示

输入: n = 1

  • 从 2 开始判断
  • 2 只出现 1 次,不符合(数字 2 出现次数应为 2)
  • 3、4、5 … 不符合
  • 22:数字 2 出现 2 次,符合 → 返回 22

输入: n = 1000

  • 从 1001 开始判断
  • 1022:含数字 0,直接排除
  • 1111:数字 1 出现 4 次,不符合
  • 1222:数字 1 出现 1 次,数字 2 出现 3 次,不符合
  • 1333:数字 1 出现 1 次,数字 3 出现 3 次,符合 → 返回 1333

总结

  • 数值平衡数是一个特别且有趣的数字定义问题;
  • 判断方法主要依赖数字频率统计;
  • 简单暴力方法在给定约束内是可行的,但如果数据范围扩大,建议预生成所有数值平衡数再查询;
  • 题目考察的是对数字特征的深刻理解及搜索/验证能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值