【一刷《剑指Offer》】面试题 12:打印 1 到最大的 n 位数

news2024/9/24 19:18:46

力扣对应题目链接:LCR 135. 报数 - 力扣(LeetCode)

牛客对应题目链接:打印从1到最大的n位数_牛客题霸_牛客网 (nowcoder.com)


一、《剑指Offer》内容


二、分析题目

1、暴力解法


2、用字符串模拟数字加法

  • 首先要考虑当 n 很大时(比如:100),打印出来的数很有可能是超过 INT_MAX 的范围,所以我们用字符串来表示每个数。
  • 当然,在这一题中,由于返回的是一个 int 型的数组,所以是不可能超过 INT_MAX 的,但是一般大数问题都不会要求返回 int 数组来保存每一位数,而是循环输出每一位数。
  • 思路:假设 n=3,定义一个字符串,初始化为 "000",然后用它来循环模拟从 1 到最大的 n 位数,并循环保存到 int 数组中(在真实情况下则是循环输出)。

3、递归全排列解法

假设 n=3,要输出的数其实就是三位数的全排列(000,001,002,...,999。注意:000 不能输出),用递归来表示出这个过程即可。


三、代码

1、暴力解法

//写法一
class Solution {
private:
    vector<int> res;
public:
    vector<int> countNumbers(int cnt) {
        int n=1;
        while(cnt--)
            n*=10;
        for(int i=1; i<n; i++)
            res.push_back(i);
        return res;
    }
};

//写法二
class Solution {
private:
    vector<int> res;
public:
    vector<int> countNumbers(int cnt) {
        for(int i=1; i<pow(10, cnt); i++)
            res.push_back(i);
        return res;
    }
};

//写法三
class Solution {
private:
    vector<int> res;
public:
    vector<int> countNumbers(int cnt) {
        string maxValue;
        while(cnt--)
            maxValue+='9';
        for(int i=1; i<=stoi(maxValue); i++)
            res.push_back(i);
        return res;
    }
};

2、用字符串模拟数字加法

class Solution {
private:
    vector<int> res;
public:
    bool increment(string& s)
    {
        bool isOverflow = false;
        int carry = 0;
        for (int i = s.size() - 1; i >= 0; i--)
        {
            int cur = s[i] - '0' + carry;
            if (i == s.size() - 1)
                cur++;
            if (cur >= 10)
            {
                if (i == 0)
                    isOverflow = true;
                else
                {
                    carry = 1;
                    s[i] = cur - 10 + '0';
                }
            }
            else
            {
                s[i] = cur + '0';
                break;
            }
        }
        return isOverflow;
    }
    void printNumbers(string& s)
    {
        bool isBeginningZero = true;
        string tmp;
        for (int i = 0; i < s.size(); i++)
        {
            if (isBeginningZero && s[i] != '0')
                isBeginningZero = false;
            if (!isBeginningZero)
                tmp += s[i];
        }
        res.push_back(stoi(tmp));
    }
    vector<int> countNumbers(int cnt) {
        if (cnt <= 0) return res;
        string s(cnt, '0');
        while (!increment(s))
            printNumbers(s);
        return res;
    }
};

3、递归全排列解法

class Solution {
private:
    vector<int> res;
public:
    void printNumbers(string& s)
    {
        bool isBeginningZero = true;
        string tmp;
        for (int i=0; i<s.size(); i++)
        {
            if(isBeginningZero && s[i]!='0')
                isBeginningZero=false;
            if(!isBeginningZero)
                tmp+=s[i];
        }
        if(tmp!="") res.push_back(stoi(tmp));
    }
    void permutation(string& s, int length, int index)
    {
        if(index==length-1)
        {
            printNumbers(s);
            return;
        }
        for(int i=0; i<10; i++)
        {
            s[index+1]=i+'0';
            permutation(s, length, index+1);
        }
    }
    vector<int> countNumbers(int cnt) {
        if(cnt<=0) return res;
        string s(cnt, '0');
        for(int i=0; i<10; i++)
        {
            s[0]=i+'0';
            permutation(s, cnt, 0);
        }
        return res;
    }
};

四、扩展

在前面的代码中,我们都是用一个 char 型字符表示十进制数字的一位。8 个 bit 的 char 型字符最多能表示 256 个字符,而十进制数字只有 0~9 的 10 个数字。因此用 char 型字符串来表示十进制的数字并没有充分利用内存,造成了一些浪费。

有没有更高效的方式来表示大数?

通过使用 string 进行求解(上面的方法都可以转换成 string 来求解,下面写一个 dfs)。

  • 第一层遍历 n,1 位数、2 位数、3 位数...
  • 因为第一位数不能取 0,所以第一位数单独拉出来遍历,故第二层遍历 1~9,代表第一位数只能取 1~9
  • 然后 dfs,遍历 2~n 的每一位数字,取值范围 0~9

注意:无需回溯,因为保存结果的是 string,不用引用传递就行。

dfs 的过程:

  • k 表示当前是第 k 个位置,当 k=n 时,dfs 终止,将 string 保存。
  • 当前位置可选 0~9,然后 dfs 下一个位置。
//大数解法(dfs)
class Solution {
private:
    vector<int> res;
public:
    void dfs(int k, int n, string s)
    {
        if(k==n)
        {
            res.push_back(stoi(s));
            return;
        }
        for(int i=0; i<10; i++)
            dfs(k+1, n, s+to_string(i));
    }
    vector<int> countNumbers(int cnt) {
        for(int i=1; i<=cnt; i++)
            for(int j=1; j<10; j++)
                dfs(1, i, to_string(j));
        return res;
    }
};

五、相关题目

定义一个函数,在该函数中可以实现任意两个整数的加法。由于没有限定输入两个数的大小范围,我们也要把它当作大数来处理。在第一个思路中,实现了在字符串表示的数字上加 1 的功能,可以参考这个思路实现两个数字的相加功能。另外还有一个需要注意的问题:

如果输入的数字中有负数,我们应该怎么去处理?

通常对于大数问题,常用的方法就是使用字符串来表示这个大数。可以先将两个整数分别用字符串来表示,然后分别将这两个字符串拆分成对应的字符数组。当两个整数都是正数的时候直接相加结果为正数,同为负数的时候取两者的绝对值相加然后在结果前加一个负号。如果是一正一负,则用两者的绝对值相减,用绝对值大的数减去绝对值小的数,当正数的绝对值大的时候相减的结果为正数,当负数的绝对值大的时候相减的结果为负数,结果为负数时在相减的结果前加一个负号即可。在具体进行相加的时候两个字符数组对应的数字字符相加即可,当有进位的时候做出标记,在更高一位进行相加时再将这个进位加进去。

tips:如果面试题是关于 n 位的整数并且没有限定 n 的取值范围,或者是输入任意大小的整数,那么这个题目很有可能是需要考虑大数问题的。字符串是一个简单、有效的表示大数的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1644859.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pandas层级索引

文章目录 第1关&#xff1a;多级索引的取值与切片第2关&#xff1a;多级索引的数据转换与累计方法 第1关&#xff1a;多级索引的取值与切片 编程要求 本关的编程任务是补全右侧上部代码编辑区内的相应代码&#xff0c;要求实现如下功能&#xff1a; 使用MultiIndex创建如下Da…

Vue3+.NET6前后端分离式管理后台实战(十七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(十七)已经在微信公众号更新&#xff0c;有兴趣的扫码关注一起交流学习。

ShardingSphere 5.x 系列【30】影子库

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 影子库与全链路压测2. 核心概念3. 使用限制4. 执行原理4.1 DML 语句4.2 D…

Vue前端环境准备

vue-cli Vue-cli是Vue官方提供的脚手架&#xff0c;用于快速生成一个Vue项目模板 提供功能&#xff1a; 统一的目录结构 本地调试 热部署 单元测试 集成打包上线 依赖环境&#xff1a;NodeJs 安装NodeJs与Vue-Cli 1、安装nodejs&#xff08;已经安装就不用了&#xff09; node-…

指挥中心操作台的选择至关重要

在指挥中心的环境中&#xff0c;操作台是核心设备&#xff0c;它承载着信息收集、处理、分发的重要任务。其选择应考虑到多方面的因素&#xff0c;包括外观、材质、稳定性、操作便利性以及技术支持等。嘉德立在这里给大家详细的总结一下选择指挥中心操作台的要点。 首先&#x…

docker挂载数据卷-以nginx为例

目录 一、什么是数据卷 二、数据卷的作用 三、如何挂载数据卷 1、创建nginx容器挂载数据卷 2、查看数据卷 3、查看数据卷详情 4、尝试在宿主机修改数据卷 5、查看容器内对应的数据卷目录 6、 访问nginx查看效果 ​​​​​​​一、什么是数据卷 挂载数据卷本质上就是实…

Ansible之性能调优

有很多人说Ansible的执行效率比SaltStack差&#xff0c;确实&#xff0c;默认使用的SSH方式通信&#xff0c;效率远低于SaltStack的zeromq消息队列。但是我们可以优化Ansible的执行速度&#xff0c;可以做到并不比SaltStack差。 1. 开启SSH长连接 在OpenSSH 5.6版本后&#xf…

【Proteus】LED呼吸灯 直流电机调速

1.LED呼吸灯 #include <REGX51.H> sbit LEDP2^0; void delay(unsigned int t) {while(t--); } void main() {unsigned char time,i;while(1){for(time0;time<100;time){for(i0;i<20;i){LED0;delay(time);LED1;delay(100-time);}}for(time100;time>0;time--){fo…

【软件测试理论002】认识软件缺陷、缺陷生命周期、缺陷分类

目录 1 认识软件缺陷 1.1 什么是软件缺陷 1.2 缺陷存在哪些方面 1.3 软件缺陷示例 1.4 软件缺陷的表现形式 1.5 软件缺陷产生的原因 1.6 软件缺陷的根源 1.7 软件缺陷修复的费用 2 软件缺陷的信息分类 2.1 软件缺陷的生命周期 2.2 软件缺陷的信息 2.3 软件缺陷分类…

论文| What makes visual place recognition easy or hard?

论文| What makes visual place recognition easy or hard?

【C语言】简单有趣的扫雷游戏

**©作者:末央&#xff06; ©系列:C语言初阶(适合小白入门) ©说明:以凡人之笔墨&#xff0c;书写未来之大梦 目录 一、分析游戏规则二、分文件三、菜单实现四、游戏内容核心实现1.初始化棋盘2.打印棋盘3.布置雷4.排查雷5.game()函数实现调用 五、全部源码 一、分…

【JAVA项目】基于ssm的协同过滤算法的【图书推荐系统】

技术简介&#xff1a;采用B/S架构、ssm 框架、Java技术、MySQL等技术实现。 系统简介&#xff1a;系统权限按管理员和用户这两类涉及用户划分。&#xff08;1&#xff09;管理员功能需求 管理员登陆后&#xff0c;主要包括首页、个人中心、用户管理、书籍管理、书籍分类管理、热…

手搓链式结构队列(C语言)

Queue.h #pragma once#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <stdbool.h>typedef int QDataType;// 链式结构&#xff1a;表示队列 typedef struct QListNode {struct QListNode* next;QDataType data; }QNode;// 队…

基于java+springboot+vue实现的新闻资讯系统(文末源码+Lw)216

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;文章信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

Java 基础重点知识-(泛型、反射、注解、IO)

文章目录 什么是泛型? 泛型有什么用?泛型原理是什么? Java 反射什么是反射? 反射作用是什么?动态代理有几种实现方式? 有什么特点? Java 注解什么是注解, 作用是什么? Java I/O什么是序列化?Java 是怎么实现系列化的?常见的序列化协议有哪些?BIO/NIO/AIO 有什么区别…

代码随想录day51 | 动态规划P12 | ● 309. ● 714. ●买卖股票总结

309.最佳买卖股票时机含冷冻期 给定一个整数数组 prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;: 卖出股票后&…

linux文本三剑客之grep

目录 1、三剑客特点和应用场景 2、三件客之grep 1) -v 参数使用示例&#xff1a; 1、三剑客特点和应用场景 命令特点场景grep过滤grep命令过滤速度最快sed替换&#xff0c;修改文件内容&#xff0c;取行 如果要进替换/修改文件内容 取出某个范围的内容&#xff08;从中午12.到…

【Unity】位图字体制作工具:蒲公英

一般来讲&#xff0c;如果需要制作位图字体&#xff0c;一般是使用 BMFont 这种第三方工具&#xff1a;BMFont - AngelCode.comhttp://www.angelcode.com/products/bmfont/ 然而这个工具对于非程序员来说&#xff0c;操作起来较为繁琐困难。每次美术修改了字体之后&…

C语言 | Leetcode C语言题解之第69题x的平方根

题目&#xff1a; 题解&#xff1a; int mySqrt(int x) {long int i 0;for(i0;;i){long int a i*i;long int b (i1)*(i1);if(a < x&&b > x){break;}}return i; }

AI部署指南

部署指南 建议大家尽可能的自己去部署&#xff0c;如果实在懒得搞&#xff0c;可以找我来帮你部署&#xff0c;详情参考 服务器代部署说明。 由于时间仓促&#xff0c;文档可能尚未详尽&#xff0c;我将在后续逐步补充详细的说明文档。 架构草图 项目依赖 必选依赖 MySQ…