题目:
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
这个问题第一眼看起来很简单,确实也很简单。但是需要注意到的是进位问题。例如:
输入:digits = [9]
输出:[1,0]
解释:9+1=10。
怎么处理这个进位问题是解这道题的关键。
错误方法:整数转化
这是我能想到的第一个方法。将整个数组中的每一位提取出来变成一个整数,然后将这个整数加一之后再每一位存回到新的数组中去。这样就完美解决了进位的问题。goodjob。然并卵。
问题主要出现在数组的长度上,数组是没有固定长度的,但是整数代表的数字是有长度的,最后运行的时候错误出现在了:
输入:digits=[7,2,8,5,0,9,1,2,9,5,3,6,6,7,3,2,8,4,3,7,9,5,7,7,4,7,4,9,4,7,0,1,1,1,7,4,0,0,6]
它太长了,即便我定义了longlong型的整数都不能代表这个数字。所以显然这个方法并不是适合很好的处理这道题目。
代码以及运算结果:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int i,k;
long long int j=1;
long long int temp=0;
long long int temp1,temp2;
int length=digits.size();
vector<int> nums;
for(i=0;i<length;i++)
{
temp=temp*10+digits[i];
}
temp=temp+1;
temp1=temp;
while(temp1/10>0)
{
//cout<<"j:"<<j<<endl;
j=j*10;
temp1/=10;
}
while(j/10>0)
{
temp2=temp/j;
nums.push_back(temp2);
temp%=j;
j/=10;
}
nums.push_back(temp);
return nums;
}
};
数组长度短一点的话这个方法是能够处理的,太长的话就不行了。
正确求解思路一:遍历
遍历真的是个很好的求解题目的方式,前面转化整数失败,我就只能将数据在数组中操作了。因为是最后一个数的加一问题,所以先对数组的最后一位进行操作。
取数组的最后一位,对其中的值加一。这里唯一需要考虑的问题是该数字是否为9,如果该数字为9,则我们还需要对前一位数字进行加一操作
…
直到考虑到第一位。
如果整个数组中所有数字都为9,例如:
输入:digits = [9,9]
因为到第0个数字还需要进一,但是不可能对数组的第-1位进行操作吧,所以这里我们应该将该数组整体右移一位,给最前面的数腾出空间。这样我们第一个数字就不再是0而是1了,然后需要在数组最后一位补0。
代码及实现:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int length=digits.size();
int add=0;
vector<int> nums;
if(length==1)
{
if(digits[0]==9)
{
digits[0]=1;
digits.push_back(0);
}
else
digits[0]+=1;
return digits;
}
while(length>0)
{
length--;
if(length==digits.size()-1)
{
int temp=digits[length];
temp += 1;
if(temp==10)
{
digits[length]=0;
add=1;
}
else
{
digits[length]=temp;
break;
}
}
else if(length>0)
{
if(add==1)
{
int temp=digits[length];
temp += add;
if(temp==10)
{
digits[length]=0;
add=1;
}
else
{
digits[length]=temp;
break;
}
}
}
if(length==0)
{
if(digits[length]==9 && add==1)
{
digits[length]=1;
digits.push_back(0);
}
else if(digits[length] !=9 && add==1)
{
digits[length]+=1;
}
else if(digits[length] ==9 && add!=1)
;
}
}
return digits;
}
};
这似乎不是最好的解题思路但确实可以解这个问题。
优化思路
这题官方给出的解题思路还是比较巧妙的。加一问题考虑的是数组从末尾开始有几个连续的9。如果从末尾开始没有连续的9,则我们只要将最后一位加一即可,如果有连续的N个9,则说明我们要操作N+1位,对第N+1位进行加一操作,后面N位置零。
特别的,针对整个数组都是9的情况,可以通过操作第一位以及最后一位的方式进行求解即可。
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int n = digits.size();
for (int i = n - 1; i >= 0; --i) {
if (digits[i] != 9) {
++digits[i];
for (int j = i + 1; j < n; ++j) {
digits[j] = 0;
}
return digits;
}
}
// digits 中所有的元素均为 9
vector<int> ans(n + 1);
ans[0] = 1;
return ans;
}
};
参考:
https://leetcode-cn.com/problems/plus-one/solution/jia-yi-by-leetcode-solution-2hor/