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

news/2024/5/19 0:48:03 标签: leetcode, 题解, 打表, 二分, 枚举

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

力扣题目链接:https://leetcode.cn/problems/next-greater-numerically-balanced-number/

如果整数  x 满足:对于每个数位 d ,这个数位 恰好x 中出现 d 次。那么整数 x 就是一个 数值平衡数

给你一个整数 n ,请你返回 严格大于 n最小数值平衡数

 

示例 1:

输入:n = 1
输出:22
解释:
22 是一个数值平衡数,因为:
- 数字 2 出现 2 次 
这也是严格大于 1 的最小数值平衡数。

示例 2:

输入:n = 1000
输出:1333
解释:
1333 是一个数值平衡数,因为:
- 数字 1 出现 1 次。
- 数字 3 出现 3 次。 
这也是严格大于 1000 的最小数值平衡数。
注意,1022 不能作为本输入的答案,因为数字 0 的出现次数超过了 0 。

示例 3:

输入:n = 3000
输出:3133
解释:
3133 是一个数值平衡数,因为:
- 数字 1 出现 1 次。
- 数字 3 出现 3 次。 
这也是严格大于 3000 的最小数值平衡数。

 

提示:

  • 0 <= n <= 106

方法一:枚举

我们可以很方便地写一个函数用来判断一个数 n n n是否为“数值平衡数”。

只需要取出这个数的每一位并统计出现次数,从0到10遍历,如果出现次数不等于这个数就返回false,否则返回true。

接下来从给定的 n n n的下一个数开始枚举,直到枚举到了“数值平衡数”为止。

  • 时间复杂度:不易计算,但是能过(方法二中也可以看出无论给定n是多少,枚举量都不超过557778)
  • 空间复杂度 O ( 1 ) O(1) O(1)

AC代码

C++
class Solution {
private:
    bool isok(int n) {
        int cnt[10] = {0};
        while (n) {
            cnt[n % 10]++;
            n /= 10;
        }
        for (int i = 0; i <= 9; i++) {
            if (cnt[i] && cnt[i] != i) {
                return false;
            }
        }
        return true;
    }

public:
    int nextBeautifulNumber(int n) {
        while (!isok(++n));
        return n;
    }
};
Python
class Solution:
    def ok(self, n: int) -> bool:
        cnt = [0] * 10
        while n:
            cnt[n % 10] += 1
            n //= 10
        for i in range(10):
            if cnt[i] and cnt[i] != i:
                return False
        return True
    
    def nextBeautifulNumber(self, n: int) -> int:
        while True:
            n += 1
            if self.ok(n):
                return n

方法二:打表

方法一中我们实现了“判断一个数是否为数值平衡数的函数”,因此我们可以写一个简单的程序,预先将所有可能用到的“数值平衡数”存下来:

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;

bool isok(int n) {
    int cnt[10] = {0};
    while (n) {
        cnt[n % 10]++;
        n /= 10;
    }
    for (int i = 0; i <= 9; i++) {
        if (cnt[i] && cnt[i] != i) {
            return false;
        }
    }
    return true;
}

int main() {
    vector<int> ok;
    int n = 0;
    while (++n) {
        if (isok(n)) {
            ok.push_back(n);
            if (n > 1000000) {
                break;
            }
        }
    }
    for (int t : ok) {
        cout << t << ", ";
    }
    puts("");
    return 0;
}

上述代码不重要,反正只要能得到下面的这个表就好:

1, 22, 122, 212, 221, 333, 1333, 3133, 3313, 3331, 4444, 14444, 22333, 23233, 23323, 23332, 32233, 32323, 32332, 33223, 33232, 33322, 41444, 44144, 44414, 44441, 55555, 122333, 123233, 123323, 123332, 132233, 132323, 132332, 133223, 133232, 133322, 155555, 212333, 213233, 213323, 213332, 221333, 223133, 223313, 223331, 224444, 231233, 231323, 231332, 232133, 232313, 232331, 233123, 233132, 233213, 233231, 233312, 233321, 242444, 244244, 244424, 244442, 312233, 312323, 312332, 313223, 313232, 313322, 321233, 321323, 321332, 322133, 322313, 322331, 323123, 323132, 323213, 323231, 323312, 323321, 331223, 331232, 331322, 332123, 332132, 332213, 332231, 332312, 332321, 333122, 333212, 333221, 422444, 424244, 424424, 424442, 442244, 442424, 442442, 444224, 444242, 444422, 515555, 551555, 555155, 555515, 555551, 666666, 1224444

这是从1到1224444的所有“数值平衡数”。有了这张表,不论给你的n等于几,你都可以通过二分等方式在极短的时间内找到第一个大于n的“数值平衡数”。

  • 时间复杂度 log ⁡ l e n ( B i a o ) \log len(Biao) loglen(Biao),其中表的大小 l e n ( B i a o ) = 110 len(Biao)=110 len(Biao)=110
  • 空间复杂度 O ( l e n ( B i a o ) ) O(len(Biao)) O(len(Biao))

AC代码

C++
const int ok[] = {1, 22, 122, 212, 221, 333, 1333, 3133, 3313, 3331, 4444, 14444, 22333, 23233, 23323, 23332, 32233, 32323, 32332, 33223, 33232, 33322, 41444, 44144, 44414, 44441, 55555, 122333, 123233, 123323, 123332, 132233, 132323, 132332, 133223, 133232, 133322, 155555, 212333, 213233, 213323, 213332, 221333, 223133, 223313, 223331, 224444, 231233, 231323, 231332, 232133, 232313, 232331, 233123, 233132, 233213, 233231, 233312, 233321, 242444, 244244, 244424, 244442, 312233, 312323, 312332, 313223, 313232, 313322, 321233, 321323, 321332, 322133, 322313, 322331, 323123, 323132, 323213, 323231, 323312, 323321, 331223, 331232, 331322, 332123, 332132, 332213, 332231, 332312, 332321, 333122, 333212, 333221, 422444, 424244, 424424, 424442, 442244, 442424, 442442, 444224, 444242, 444422, 515555, 551555, 555155, 555515, 555551, 666666, 1224444};

class Solution {
public:
    int nextBeautifulNumber(int n) {
        return *upper_bound(ok, ok + sizeof(ok) / sizeof(int), n);
    }
};
Python
# from bisect import bisect_right

ok = [1, 22, 122, 212, 221, 333, 1333, 3133, 3313, 3331, 4444, 14444, 22333, 23233, 23323, 23332, 32233, 32323, 32332, 33223, 33232, 33322, 41444, 44144, 44414, 44441, 55555, 122333, 123233, 123323, 123332, 132233, 132323, 132332, 133223, 133232, 133322, 155555, 212333, 213233, 213323, 213332, 221333, 223133, 223313, 223331, 224444, 231233, 231323, 231332, 232133, 232313, 232331, 233123, 233132, 233213, 233231, 233312, 233321, 242444, 244244, 244424, 244442, 312233, 312323, 312332, 313223, 313232, 313322, 321233, 321323, 321332, 322133, 322313, 322331, 323123, 323132, 323213, 323231, 323312, 323321, 331223, 331232, 331322, 332123, 332132, 332213, 332231, 332312, 332321, 333122, 333212, 333221, 422444, 424244, 424424, 424442, 442244, 442424, 442442, 444224, 444242, 444422, 515555, 551555, 555155, 555515, 555551, 666666, 1224444]

class Solution:
    def nextBeautifulNumber(self, n: int) -> int:
        return ok[bisect_right(ok, n)]

同步发文于CSDN,原创不易,转载经作者同意后请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/134900679


http://www.niftyadmin.cn/n/5251736.html

相关文章

【Rust】第二节:入门(如入)

1 说明 包含"Hello, world!“以及"Hello, cargo!” 环境&#xff1a;MacOS 2 Hello world 2.1 运行 1、建一个目录 2、用vscode打开 3、新建文件main.js 4、输入 fn main(){println!("Hello, world!"); }5、打开终端&#xff0c;执行rustc main.rs 6、…

LeetCode力扣每日一题(Java):27、移除元素

一、题目 二、解题思路 1、我的思路 因为题目中说“元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。”也就是说&#xff1a; 输入&#xff1a;nums [3,2,2,3], val 3 输出&#xff1a;2, nums [2,2] 解释&#xff1a;函数应该返回新的长度 2并且 nums 中的…

第二次上机测试:Javascript. (第一组)

需求&#xff1a;&#xff08;注意在规定的时间&#xff0c;在自己的博客提交作品&#xff0c;便于统计测试的完成情况。博客题目《第二次上机测试&#xff1a;Javascript.》&#xff09; 1、点击按钮&#xff0c;将图片加上边框 2、点击按钮&#xff0c;将图片缩小为长和宽都…

sql2005日志文件过大如何清理

由于安装的时候没有计划好空间&#xff0c;默认装在系统盘&#xff0c;而且又没有做自动备份、截断事务日志等&#xff0c;很快LDF文件就达到十几G&#xff0c;或者几十G &#xff0c;此时就不得不处理了。 备份和计划就不说了&#xff0c;现在就说下怎么把它先删除吧&#xf…

pytorch 钩子函数hook 详解及实战

文章目录 1. 介绍1.1 pytorch hook 函数种类1.2 pytorch hook 种类1.3 hook的执行顺序2. torch.Tensor.register_hook()2.1 功能2.2 语法2.3 案例3. nn.Module.register_forward_pre_hook3.1 功能3.2 语法3.3 案例4. nn

Photoshop Circular Text

Ctrl N 新增 现学现卖

【PyQt学习篇 · ⑫】:QVBoxLayout和QHBoxLayout布局管理器的使用

文章目录 QVBoxLayout和QHBoxLayout的介绍.addStretch()的使用方法.setSpacing()方法的使用.setAlignment()的使用.setFixedSize()的使用QMainWindow中使用布局管理器 QVBoxLayout和QHBoxLayout的介绍 QVBoxLayout 和 QHBoxLayout 是 PyQt 中用于实现垂直和水平布局的两个布局…

C#的线程技术及操作

每个正在操作系统上运行的应用程序都是一个进程&#xff0c;一个进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元&#xff0c;在进程中可以有多个线程同时执行代码。每个线程都维护异常处理程序、调度优先级和一组系统用于在调度该线程前保存线程上下文的…