作者:丁宋涛

数组:加一

题干:

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

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

你可以假设除了整数 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. 原生js实现简单的下拉刷新功能

    前言: 我们在浏览移动端web页面的时候,经常会用到下拉刷新. 现在我们用原生的js实现这个非常简单的下拉刷新功能. (温馨提示:本文比较基础,功能也很简单.写的不好的地方,希望大神提点一二.) 一. ...

  2. [Atcoder2292] Division into Two

    题目大意 给定n个不同的整数,求将它们分成两个集合X,Y,并且X集合中任意两个数的差>=A,Y集合中任意两个数的差>=B的方案数. 样例输入 5 3 7 1 3 6 9 12 样例输出 5 ...

  3. CF293E Close Vertices 点分治+树状数组

    开始zz写了一个主席树,后来发现写个树状数组就行~ #include <cstdio> #include <vector> #include <algorithm> ...

  4. python中assert的用法

    assert:断言 格式: assert 表达式 [, 参数] 当表达式为真时,程序继续往下执行: 当表达式为假时,抛出AssertionError错误,并将  参数  输出 举例: def foo( ...

  5. unittest详解(七) 自动生成测试报告

    用例执行完成后,执行结果默认是输出在屏幕上,其实我们可以把结果输出到一个文件中,形成测试报告. unittest自带的测试报告是文本形式的,如下代码: import unittest if __nam ...

  6. ID生成 雪花算法

    /** * ID生成 雪花算法 */ public class SnowFlake { public static SnowFlake getInstance() { return Singleton ...

  7. Linux安装并使用Ludwig训练模型

    一.在Python3环境安装Ludwig: 1.使用pip安装:pip install ludwig 2.源码编译安装: git clone git@github.com:uber/ludwig.gi ...

  8. mysql 日期转换sql函数

    mysql提供了两个函数: from_unixtime(time_stamp)   ->  将时间戳转换为日期 unix_timestamp(date)             ->  将 ...

  9. 分布式-信息方式-ActiveMQ的Destination高级特性2

    使用filtered destinations,在xml配置如下: <destinationInterceptors> <virtualDestinationInterceptor& ...

  10. eclipse安装错误的解决办法

    eclipse安装错误的解决办法 Eclipse 是一个集成开发环境,如Java,C,C++,PHP等安装Eclipse首先得先安装java的Jdk或者Jre 首先访问https://www.ecli ...