1.题目:
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位,数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
1.1 示例:
示例 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.2 提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
2. 思路:
-
拿到题目我还在想是不是理解错题目了,感觉这个题也太简单了点吧,看了官方题解发现果然是没有考虑到全部的情况【没有考虑末尾是9的情况】,所以才会觉得超级简单。下面就开始分析题目吧~
-
题目要求给出一个数组,这个数组中的元素组成一个非负整数。假如给的是 [1, 2, 3] , 那么这个非负整数就是123; 如果给出一个数组 [1, 2, 9, 9] , 那么这个非负整数就是1299; 如果给出一个数组是[9, 9, 9], 那么这个非负整数就是999。在这个数的基础上“加1”,并且以数组的形式输出。还是用上面的例子,[1, 2, 3] 表示数字123 ,加1后就是124, 用数组形式表示就是[1, 2, 4]; [1, 2, 9, 9]表示数组1299,加1后就是1300,用数组形式表示就是[1, 3, 0 ,0];[9, 9, 9]表示数字999,加1后就是1000,用数组形式表示就是[1, 0, 0, 0]。
-
从上面的例子我们可以发现一个规律,那就是所给出的数组只可能有2种情况:
①:所给出的数组中所有元素均为9;
②:除了①之外的所有情况;
针对情况①, 结合例子[9, 9, 9],得出结论:如果所给出的数组中所有元素均为9,那么输出的新数组要比原来的数组长度加1,并且新数组第1位为1,其余所有位为0。
针对情况②,结合例子 [1, 2, 3] 和例子[1, 2, 9, 9]来理解。 [1, 2, 3]加1后输出为[1, 2, 4],这个很简单啦;[1, 2, 9, 9]加1后输出[1, 3, 0 ,0],因为末尾有9所以需要“向前进1”,但是在数组层面如何表示这个“向前进1”呢?经过观察可以发现:对数组从后向前进行遍历,找出第一个“非9”的数字,然后将这个数字“加1”,该数字后面的数字全部变为0即可。例如数组 [1, 2, 9, 9] ,第一个非9的数字就是 2 ,加1后就是3,将该数字后面的数字全部变为0就是[1, 3, 0 ,0]啦。再想想看,数组 [1, 2, 3] 第一个非9的数字是3,给它加1就是4,将该数字后面的数字全部变为0,该数字后面没有数字,所以忽略即可。所以其实 [1, 2, 3] 也好,[1, 2, 9, 9] 也好,只需要一种判定模式:从后向前找出第一位“非9”的数字,然后将其加1,其后方所有数字全部变为0即可。
3. Python3代码:
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
n = len(digits)
for i in range(n-1, -1, -1):
if digits[i] != 9:
digits[i] += 1
for j in range(i+1, n):
digits[j] = 0
return digits
return [1] + [0]*n
【解析】
① 首先注意第一层 for 循环的range里的参数。讲解一下 range(start, stop,step):start表示起始位,stop代表结束位,step代表步长。需要注意的是[start,stop),是左闭右开的关系,也就是说取不到stop的值。而代码段中的写法 range(n-1, -1, -1)则代表着“逆序”,因为代码段中的步长值为“-1”,所以很显然就是逆序遍历了;而stop的值为-1,所以最多取到0就停止了。
② 内层 for 循环表示在逆序遍历中找到了第一位“非9”的数位(第i位)后,将其后方的数字全部设置为0。想想看,如果是数组 [1, 2, 3] ,那么第一位“非9”的数字就是3,此时 i = 2 。此时看内层的for循环,range(i+1 , n), i+1 = 3,n = 3, 所以此时内层 for 循环就不起作用啦~ 过分巧妙!
③ 两层 for 循环遍历后,剩余的只有:元素全为9的数组了。此时按照我们前文分析的情况1,直接返回一个:长为n+1, 首位为1, 其余位全部为0的数组。
4. 复杂度分析:
时间复杂度:O(n)。
【理由如下】
来自: MelodyC2E_Y
虽然本题的代码是双层for循环,一眼看上去可能会立刻给出时间复杂度是O(n2),但是本题的时间复杂是却是O(n)。理由如下:
① 如果 if digits[i] != 9 条件成立,那么就会执行内层for循环,此时一定要注意执行完内层for循环就 "return"了,就是说:不会再执行外层for循环了。一定一定要注意这个 return digits 这句是写在if 语句块里的!
② 如果 if digits[i] != 9 条件不成立,那么就不会执行内层for循环。
③ 综上:时间复杂度为O(n)。
空间复杂度:O(1):返回值不计入空间复杂度。