LeetCode加一 Java与Python3解法对比
LeetCode 加一 精讲
这道题表面简单,却是面试中高频出现的“边界条件陷阱”题。给定一个非空整数数组,每个元素存储一位数字,整体表示一个非负整数,例如 [1,2,3] 对应数字 123。现在要求对该整数执行加一操作,并返回结果数组。
最高位数字位于数组首部。可以假设除整数 0 本身外,该整数不会以零开头,即输入不会出现 [0,1,2] 这种形式。
英文题目描述:Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit. You may assume the integer does not contain any leading zero, except the number 0 itself.
先看两个典型用例:
示例 1:
输入: [1,2,3] 输出: [1,2,4] 解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1] 输出: [4,3,2,2] 解释: 输入数组表示数字 4321。
直觉上直接转成整数加一即可,但数组长度可能达到几千位,超出普通整型范围。因此必须采用“竖式加法”逐位模拟。
Java 解法:
class Solution {
public int[] plusOne(int[] digits) {
for (int i = digits.length - 1; i >= 0; i--) {
if (digits[i] + 1 == 10) {
digits[i] = 0;
} else {
digits[i] += 1;
break;
}
}
if (digits[0] == 0) {
int[] result = new int[digits.length + 1];
result[0] = 1;
return result;
} else {
return digits;
}
}
}
核心思路:
逻辑非常直接:从数组最右侧(即个位)开始向左遍历。如果当前位加一后等于10,则产生进位,将该位置零后继续处理前一位;若加一后小于10,则加一操作结束,跳出循环。一个容易遗漏的边界情况:当所有位都进位(例如 [9,9,9]),循环结束时数组首位变为0,此时需要新建一个长度加一的数组,将首位设为1,其余位全为0。上述Java代码正是按此流程实现——先处理进位,最后检查首位是否为0,若为0则扩容。
Python3 解法:
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
"""
:type digits: List[int]
:rtype: List[int]
"""
num = 0
for digit in digits:
num = num * 10 + digit
return [int(c) for c in str(num + 1)]
Python3 的解法更加灵活。上述方式直接将数组拼接成整数,加一后再转为字符数组。思路简洁,但需注意:若数组长度极大(如几千位),Python虽能处理大整数,但转为字符串再拆分仍属于取巧方案。当然也可以模仿Java手动处理进位,或利用Python列表动态特性。
例如:先将数组反转,reversed(digits),然后逐位加一并处理进位;若处理完最高位后仍需要进位(即首位为0),直接在数组末尾追加一个1,最后再反转回来。由于Python列表支持动态扩展,无需像Java那样新建固定长度数组,代码更为紧凑。
