题目描述:
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。
示例:
输入:digits = [4,3,2,1] 输出:[4,3,2,2] 解释:输入数组表示数字 4321。
解题方法1:首先想到的就是先将给定数组转换成 String 字符串,再将 String 字符串转换成整数,然后给这个整数加 1,之后将这个整数的每一位数字转按照顺序赋值到数组的每一位即可。代码如下:
/**
* 数组转字符串,字符串转整数,整数加1之后转成数组
* @param digits
* @return
*/
public static int[] plusOne2(int[] digits) {
String s = "";
for (int i = 0; i< digits.length; i++) {
s += String.valueOf(digits[i]);
}
String newStr= String.valueOf(Integer.parseInt(s) + 1);
char[] charArray = newStr.toCharArray();
int[] result = new int[charArray.length];
for (int i = 0; i < charArray.length; i++) {
result[i] = Integer.parseInt(String.valueOf(charArray[i]));
}
return result;
}
但是这样的话仅能处理一部分数据,因为代码中的 Integer.parseInt(s) 仅仅支持 Integer 范围的 s,超出范围的会转换错误。所以我们得考虑另一种方法。
解题方法2:复制数组,将原数组 digits[] 的每一位赋值到新数组 result[] 的 i + 1 位上。由于只是给数组的最后一位元素加 1,所以我们先单独处理最后一位元素。之后循环原数组 0 ~ size -2 位的元素,处理时需要关注后一位有没有产生进位的情况以及改为元素处理完成之后会不会产生向上进位的情况,即判断 result[i + 1] == 1 && digits[i] == 9,如果成立,证明后一位出现进位的情况,同时处理之后该位也会产生向上进位的情况,所以此时进行的操作是:result[i + 1] = 0 以及 result[i] = 1;如果不成立,那就属于后一位出现进位情况且处理之后该位不会出现向上进位的情况和后一位未出现进位的情况,此时需要进行的操作是:result[i + 1] = digits[i] + result[i + 1] 以及 result[i] = 0。整个数组处理完成之后,我们需要根据新数组 result[0] 的元素是否等于 1 去决定是否要截取新数组作为返回结果。具体处理过程为:假设入参 digits[] = {9, 6, 3, 9, 5, 2, 0, 9},则每次处理过程为:
循环之前我们先 new 一个新数据 result[],大小为 digits.size + 1。
首先我们处理 digits 的最后一位,即 digits[7] = 9,需要进位,所以此时我们直接写死 result[] 数组的最后一位,即 result[8] = 0,因为进位了,所以 result[7] = 1。接下来循环处理数组中剩下的元素。
i = 6:digits[6] = 0,result[ i + 1] = result[7] = 1。后一位有出现进位情况,该位不会出现向上进位的情况,所以,result[7] = digits[6] + result[7] = 1,result[6] = 0;
i = 5:digits[5] = 2,result[ i + 1] = result[6] = 0。后一位没有出现进位情况,该位不会出现向上进位的情况,所以,result[6] = digits[5] + result[6] = 2,result[5] = 0;
i= 4:digits[4] = 5,result[ i + 1] = result[5] = 0。后一位没有出现进位情况,该位不会出现向上进位的情况,所以,result[5] = digits[4] + result[5] = 5,result[4] = 0;
i= 3:digits[3] = 9,result[ i + 1] = result[4] = 0。后一位没有出现进位情况,该位不会出现向上进位的情况,所以,result[4] = digits[3] + result[4] = 9,result[3] = 0;
i= 2:digits[2] = 3,result[ i + 1] = result[3] = 0。后一位没有出现进位情况,该位不会出现向上进位的情况,所以,result[3] = digits[2] + result[3] = 3,result[2] = 0;
i= 1:digits[1] = 6,result[ i + 1] = result[2] = 2。后一位没有出现进位情况,该位不会出现向上进位的情况,所以,result[2] = digits[1] + result[2] = 6,result[1] = 0;
i= 0:digits[0] = 9,result[ i + 1] = result[1] = 0。后一位没有出现进位情况,该位不会出现向上进位的情况,所以,result[1] = digits[0] + result[1] = 9,result[0] = 0。
由于处理完成之后的 result[0] == 0,所以将该数组第一位元素去掉,然后返回 result 即可。
完整代码如下:
public class PlusOne {
public static int[] plusOne(int[] digits) {
int size = digits.length;
int[] result = new int[size + 1];
if (digits[size - 1] == 9) {
result[size] = 0;
result[size - 1] = 1;
} else {
result[size] = digits[size - 1] + 1;
result[size - 1] = 0;
}
for (int i = size - 1; i >= 0; i--) {
if (digits[i] == 9 && result[i + 1] == 1) {
// 后一位出现进位情况,且处理进位之后该位也需向上进位
result[i + 1] = 0;
result[i] = 1;
} else {
// 后一位出现进位情况,处理之后该位不会向上进位
// 后一位未出现进位情况
result[i + 1] = digits[i] + result[i + 1];
result[i] = 0;
}
}
if (result[0] == 0) {
result = Arrays.copyOfRange(result, 1, result.length);
}
return result;
}
/**
* 数组转字符串,字符串转整数,整数加1之后转成数组
* @param digits
* @return
*/
// public static int[] plusOne2(int[] digits) {
// String s = "";
// for (int i = 0; i< digits.length; i++) {
// s += String.valueOf(digits[i]);
// }
// String newStr= String.valueOf(Integer.parseInt(s) + 1);
// char[] charArray = newStr.toCharArray();
// int[] result = new int[charArray.length];
// for (int i = 0; i < charArray.length; i++) {
// result[i] = Integer.parseInt(String.valueOf(charArray[i]));
// }
// return result;
// }
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int [] digits = new int[]{1,9,7};
int[] result = plusOne(digits);
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
System.out.println();
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
}
}