目录
一、题目描述
二、初次解答
1. 思路:首先令数组末尾元素+1,若结果为10则需要进位(设置进位flag为1)。其次,对于非末尾元素,判断是否需要进位,若是则元素+1,否则仅复制。最后,判定首位元素是否需要进位,若需要进位则将其他元素后移,并在首位至1.
2. 代码:
/** * Note: The returned array must be malloced, assume caller calls free(). */ int* plusOne(int* digits, int digitsSize, int* returnSize) { int* ret = (int*)malloc(sizeof(int) * (digitsSize + 1)); //从最后开始+1,考虑进位,将结果置于ret int flag = 0; for(int i = digitsSize - 1; i >= 0; i--){ int tmp = digits[i]; if (flag == 1 || i == digitsSize - 1){ tmp++; } if (tmp == 10){ ret[i] = 0; flag = 1; } else { ret[i] = tmp; flag = 0; } } //最高位需要进位,则全部往后移动,并给最高位1 if (flag == 1){ for (int i = digitsSize - 1; i >= 0; i--){ ret[i+1] = ret[i]; } ret[0] = 1; *returnSize = digitsSize + 1; } else { *returnSize = digitsSize; } return ret; }
3. 优点:容易想到。
4. 缺点:若出现9999的情况,存在往后移动的操作,造成运行时间稍长。同时,不管是否超位都会申请空间,造成了内存资源浪费。
三、官方解法
1. 思路:对数组digits 进行一次逆序遍历,找出第一个不为9的元素,将其加一并将后续所有元素置零。如果digits中所有的元素均为9,则创建一个新数组(长度为原数组+1),将首位置1,其他位置0.
2. 代码:
/** * Note: The returned array must be malloced, assume caller calls free(). */ int* plusOne(int* digits, int digitsSize, int* returnSize) { //寻找最长的后缀9,将非9元素+1,并将后所有的9置为0 for (int i = digitsSize-1; i >= 0; --i) { if (digits[i] != 9) { ++digits[i]; for (int j = i + 1; j < digitsSize; ++j) { digits[j] = 0; } *returnSize = digitsSize; return digits; } } //digits中所有元素均为9 int* ret = (int*)malloc(sizeof(int) * (digitsSize + 1)); memset(ret, 0, sizeof(int) * (digitsSize + 1));//全部置0 ret[0] = 1; *returnSize = digitsSize + 1; return ret; }
3. 优点:①不存在往后移动的操作,提升程序运行速度,时间复杂度为O(n)。②代码更简洁。
4. 缺点:还是不够快。
四、C++写法
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
//从后往前将9元素置为0
int i = digits.size() - 1;
while (i >= 0 && digits[i] == 9) {
digits[i--] = 0;
}
//若超出则头插1
if (-1 == i) {
digits.insert(digits.begin(), 1);
} else {
digits[i]++;
}
return digits;
}
};
五、总结
考虑进位时,可以反向遍历找到后缀非9的元素并使其+1,再将后续所有的元素置为0。另外,给动态分配的数组批量赋值时,可以考虑使用memset函数。