题目链接
https://leetcode-cn.com/problems/plus-one/
题目
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
题目可能有些绕口,说的就是把一个数字比如123,把每个位上的数字放入数组当中,要求把这个数+1,然后放回数组。这个数字是非空的整数,首位不会出现0。
示例
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。示例 3:
输入:digits = [0]
输出:[1]
提示
1 <= digits.length <= 100
0 <= digits[i] <= 9
思路
这题我第一反应是,先把数组变成一个数字变量,然后把这个数字变量+1,再将其放到数组当中即可。代码如下所示:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int n=digits.size();
long long int sum=0;
//对每位代表的值进行相加,把数组变成一个数字sum
for(int i=n-1;i>=0;i--)
{
sum=sum+digits[i]*pow(10,n-i-1);
}
//对这个数+1
sum++;
n=0;
long int a=sum;
//求出这个数+1后的位数n,有可能从位数会变长一位,如从9变成10。
while(a)
{
a/= 10;
n++;
}
//新建一个新的长度为n的数组
vector<int> new_digits(n,0);
//将每一位上的数重新放入数组
for(int i=n-1;i>=0;i--)
{
new_digits[i]=sum/(long long int)pow(10,n-i-1)%10;
}
return new_digits;
}
};
但是,这样做有个大问题,我们从题目提示里可以看出, 1 <= digits.length <= 100,
也就是说这个数可能高达100位,会导致计算过程中溢出以及精度不够。因此,以上方法不可行。
于是,我们考虑直接从数组下手进行操作,对于普通的数,比如1、18、123这样的数,直接在数组最后加1就行,因此这题重点需要考虑的就是:9->10、189->190、19999->20000这些出现了9的情况,有可能会导致一些列的位上都发生了变化,甚至可能使数组变长。在这里,我们分情况讨论:
1. 对于123这样末位不为9的数:直接末位+1即可。
2. 对于189、2999、3399这样末位为9但其他位不全为9的数:
从末位开始遇到9就赋值0,直到遇到第一个不为9的位,该位上的数+1,然后就可以跳出循环。
例如,对于3399这个数,首先从末位开始,遇到了第一个9,把9置0,
移动到下一位,还是9,置0,
再接着下一位,遇到3,把3+1变成4,此时就可以结束了。
3. 对于9、99、999这样所有位都为9的数:
位数+1,也就是数组长度+1,
这时我们新建一个新的数组,首位赋值1,其他位全0即可。
代码如下:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
//情况一、二均由for循环处理
//对于情况一,第一次if判断出末位不为9,将该位+1便可得到结果
//对于情况二,将遇到的所有9都变成0,直到遇到第一个不为9的数,+1,得到结果
for (int i = digits.size() - 1; i >= 0; i--)
{
if (digits[i] != 9)
{
digits[i]++;
return digits;
}
digits[i] = 0;
}
//如果跳出for循环,说明是情况三,即每一位都是9,新建长度+1的数组,首位为1,其余为全0
vector<int> new_digits(digits.size() + 1,0);
new_digits[0] = 1;
return new_digits;
}
};