作者:丁宋涛

数组:加一

题干:

给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

参考样例:

示例 1:

输入: [1,2,3]

输出: [1,2,4]

解释: 输入数组表示数字 123。

示例 2:

输入: [4,3,2,1]

输出: [4,3,2,2]

解释: 输入数组表示数字 4321。

这道题是一道数组的基础题,其本质是一道模拟计算题。

这道题有一定的工程应用意义,大家都知道,计算机的浮点数运算有误差,究其细节有相当数量的开发者却往往不求甚解。请看:

做开发的朋友都知道计算机在程序处理中,都是将十进制数转成二进制数进行运算的。对于这种转化,其方法就是除2逆向取余法,例如:

十进制数13转成二进制的方法就是

转化成数学表达式就是(13)10=(1101)2

对于十进制小数转化成二进制小数使用的方法是乘2正向取整法,比如十进制的0.75

即(0.75)10=(0.11)2

如果,我们考虑下将十进制的0.6转化成二进制呢?如果依然使用乘二正向取整法会发生什么呢?

如果从数学上讲,(0.75)10=(0.1001)2

为什么会出现这种循环表示呢?因为数学上有证明,十进制表示法与二进制表示法,仅仅在整数范围内才有明确的对应的关系,而小数部分是做不到的。因此,在采用二进制运算上,计算机的数值求解是有缺陷的。

意识到这一点,我们就会问那么是不是我们现在和小数点相关的运行都是不可靠的呢?显然不可能,最常见的就是我们的金融活动。大凡和交易有关的数据,那是一个数字都不能出错的,那么他们背后的计算过程又是如何保证的呢?

答案就是模拟计算。

在小学数学课本上就教过这样的案例:123.4+5.67,我们来看,加数与被加数的位数并不相同,小学老师在教学中一定会强调对齐小数点,其过程如下:

这个在计算机中有一个术语叫做对阶。所谓阶就是进制,十进制的阶就是10,二进制的阶就是2,具体的数学表达就是

123.4 = 1×102+2×101+3×100+4×10-1

5.67=5×100+6×10-1+7×10-2

我们知道计算机的整数运算是没有缺陷的,如果我们这样做,是不是就可以达到精确求解的目的了?

123.4+5.67=(12340+567)×10-2=12907×10-2=129.07

这就是精度计算中的常用的计算思想,这也是为什么在以Java为核心语言中做交易系统中,金额通常不用float,double而用decimal类型的原因。

明白了这个知识,我们就知道了这个看似普通的题目,其实是企业开发商用软件中的一个现实问题。那么,在现实计算中,人们又是如何来处理上述的对阶、运算的过程呢?答案就是数组。我们用数组来模拟每一位,然后用小学数学课本教授的方法,手工计算出就可以了。

下面回到这个题目:题目的函数签名是这样的:vector<int> plusOne(vector<int>& digits)

传入的参数是digits,是一个整型的向量,其位数按照角标升序排列,即角标0对应的是数字的最高位,最后一位表示的数字的最低位,比如参考样例:[1,2,3],他表示的是十进制123,角标0对应的是百位1,角标2对应的是个位3.模拟十进制计算的过程,就是逢10进位,这道题我们首先要找到最低位,如果最低位不是9,直接取出角标对应的数值加1即可,如果是数字的9的话,那么直接将其改为0,并向其上一位角标对应的数字加1.需要注意的细节是,如果这个数字恰好是[9,9,9],那么返回值应当增加1位得到[1,0,0,0]。为了方便编程,我们从最后一位开始。代码如下:

1 vector<int> plusOne(vector<int>& digits) {

2        int n = digits.size();

3        for(int i=n-1;i>=0;i--){

4            if(digits[i] == 9)

5                digits[i] =0;

6            else {

7                digits[i]++;

8                return digits;

9            }

10        }

11        digits[0] =1;

12        digits.push_back(0);

13        return digits;

14 }

第2行,首先获得当前向量digits的长度,并将其复制给n,然后从角标n-1开始,逆向遍历整个数组,由于i是从n-1开始,我们先判断当前位置是否是9,如果是9,那么就把把当前位置置0,并向前遍历到前一个位置,只要前一个位置不是9,那么就把此时的位置加1,然后返回。如果全体循环结束都没有返回,那么说明传入的必然是999这种类型的。那么出了循环之后,先把角标0改为1,并再增加一个0,就完成了全部的计算过程。

Leetcode基础篇30天30题系列之数组:模拟计算法的更多相关文章

  1. C++基础知识面试精选100题系列(11-20题)[C++ basics]

    [原文链接] http://www.cnblogs.com/hellogiser/p/100-interview-questions-of-cplusplus-basics-11-20.html [题 ...

  2. C++基础知识面试精选100题系列(1-10题)[C++ basics]

    [原文链接] http://www.cnblogs.com/hellogiser/p/100-interview-questions-of-cplusplus-basics-1-10.html [题目 ...

  3. C++基础知识面试精选100题系列(21-30)[C++ basics]

    [本文链接] http://www.cnblogs.com/hellogiser/p/100-interview-questions-of-cplusplus-basics-21-30.html [题 ...

  4. PHP 基础篇 - PHP 的 BC MATH 系列数学函数

    一.常见问题 用 PHP 做计算时经常会遇到精度带来的问题,下面来看两个常见的例子: 1. 运算比较 下面表达式输出的结果不是相等: <?php echo 2.01 - 0.01 == 2 ? ...

  5. 【Java 基础篇】【第二课】基本数组类型

    就像第一章所说一样,这次学习为了快,因此说明性的文字就不想写太多了,直接帖代码吧,代码当中尽量加一些注释: package a.b; public class test { static void B ...

  6. [ 9.11 ]CF每日一题系列—— 441C暴力模拟

    Description: n * m 的地图,建设k个管道管道只能横竖走,且长度大于等于2,问你任意一种建设方法 Solution: 图里没有障碍,所以先把前k - 1个管道每个分2个长度,最后一个管 ...

  7. SQL Server调优系列基础篇(联合运算符总结)

    前言 上两篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符的优化技巧,本篇我们总结联合运算符的使用方式和优化技巧. 废话少说,直接进入本篇的主题. 技术准备 基于SQL Server200 ...

  8. SQL Server调优系列基础篇(并行运算总结)

    前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自 ...

  9. SQL Server调优系列基础篇(并行运算总结篇二)

    前言 上一篇文章我们介绍了查看查询计划的并行运行方式. 本篇我们接着分析SQL Server的并行运算. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版 ...

随机推荐

  1. Kendo UI for jQuery使用教程:方法和事件

    [Kendo UI for jQuery最新试用版下载] Kendo UI目前最新提供Kendo UI for jQuery.Kendo UI for Angular.Kendo UI Support ...

  2. Redis的部署使用文档

    Redis的部署使用文档   简述: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符 串).list(链表).set( ...

  3. Atcoder Regular Contest 066 F genocide【JZOJ5451】

    题目 分析 \(s[i]\)表示a前缀和. 设\(f[i]\)表示做完了1~i的友谊颗粒的最优值(不一定选i),那么转移方程为 \[f[i]=max\{f[i-1],max\{f[j]-s[i]+s[ ...

  4. electron桌面通知,修改默认通知应用名electron.app.Electron为自己应用的名称

    在做electron桌面通知时,按照文档实现弹出通知,但是默认的应用名为electron.app.Electron 解决办法 就是在主进程中设置 app.setAppUserModelId('myAp ...

  5. yum 源的搭建

    repos和epel的关系 https://blog.csdn.net/fantaxy025025/article/details/84918199 配置阿里云的yum源 https://www.cn ...

  6. 计算机网络(十一),HTTP和HTTPS区别

    目录 1.SSL(Security Sockets Layer,安全套接层) 2.加密方式 3.HTTPS数据传输流程 4.HTTP和HTTPS的区别 5.HTTP真的很安全吗 十一.HTTP和HTT ...

  7. props 父组件给子组件传递参数

    话不多说,直接上代码 父组件: <span><humidity-component ref="soilHumidityBot" :title='title2'&g ...

  8. Housewife Wind

    Housewife Wind 参考博客:POJ2763 Housewife Wind(树剖+线段树) 差不多是直接套线段树+树剖的板子,但是也有一些需要注意的地方 建树: void build() { ...

  9. python学习之路(14)

    通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素 ...

  10. mysql 查询一个月的数据

    //今天 select * from 表名 where to_days(时间字段名) = to_days(now()); //昨天 SELECT * FROM 表名 WHERE TO_DAYS( NO ...