刷题笔记:力扣第66题-加一

📅 发布时间:2026/7/11 19:18:10 👁️ 浏览次数:
刷题笔记:力扣第66题-加一
1.拿到题目的初步想法是将数组中的数取出来还原成完整的整数sum然后将这个整数1判断是否进位然后再逆序将sum的值放入自己开辟空间的整形数组里面。初步的代码如下1. /** 2. * Note: The returned array must be malloced, assume caller calls free(). 3. */ 4. int* plusOne(int* digits, int digitsSize, int* returnSize) { 5. int i; 6. int sum 0; 7. for (i 0; i digitsSize; i){ 8. sum digits[i] * pow(10, digitsSize - i - 1); 9. } 10. sum; 11. if ((sum / pow(10, digitsSize)) 1){ 12. *returnSize digitsSize 1; 13. } else { 14. *returnSize digitsSize; 15. } 16. int* returnArray (int*)malloc(*returnSize * sizeof(int)); 17. for (i *returnSize - 1; i 0; i--){ 18. returnArray[i] sum % 10; 19. sum / 10; 20. } 21. return returnArray; 22. }2.程序在运行测试案例中没问题但是提交后报错了如下图可以看到数组里面出现了本不可能出现的负数说明溢出了测试用例中给出的数已经超出了int的范围即使换成long也会在后续测试中溢出而且数组长度上限为100扩大整数大小范围不是正确的做法。3.咨询了ai由于溢出的问题最初的想法是不可行的正确的做法应该是直接在数组中模拟进位如果出现进位导致数组长度1则特殊讨论。代码如下1. /** 2. * Note: The returned array must be malloced, assume caller calls free(). 3. */ 4. int* plusOne(int* digits, int digitsSize, int* returnSize) { 5. int i, j; 6. 7. // 1. 从最后一位个位向前遍历处理加1和进位 8. for (i digitsSize - 1; i 0; i--){ 9. // 2. 当前位加1核心操作 10. digits[i] 1; 11. 12. // 3. 关键判断当前位加1后无进位10 13. if (digits[i] 10){ 14. // 3.1 设置返回数组长度为原长度 15. *returnSize digitsSize; 16. // 3.2 分配返回数组内存题目要求malloc 17. int* returnArray (int*)malloc(*returnSize * sizeof(int)); 18. // 3.3 复制原数组加1后无进位的结果到返回数组 19. for (j 0; j *returnSize; j){ 20. returnArray[j] digits[j]; 21. } 22. // 3.4 直接返回无需处理后续位 23. return returnArray; 24. } 25. 26. // 4. 有进位当前位重置为0继续处理前一位 27. digits[i] 0; 28. } 29. 30. // 5. 执行到这里说明所有位都进位了如999→1000 31. // 5.1 设置返回数组长度为原长度1 32. *returnSize digitsSize 1; 33. // 5.2 分配新长度的内存 34. int* returnArray (int*)malloc(*returnSize * sizeof(int)); 35. // 5.3 初始化新数组最高位为1其余位为0 36. for (i 0; i *returnSize; i){ 37. if (i 0){ 38. returnArray[i] 1; // 新增的最高位 39. } else { 40. returnArray[i] 0; // 原数组所有位都进位为0 41. } 42. } 43. // 5.4 返回扩容后的数组 44. return returnArray; 45. }4.由于本题只是1所以如果发生进位只可能是当前位1且不会超过10。所以在第一个for循环里面不断进行当前位是否小于10的判断如果小于10就说明后面也不会出现进位了且不是999这种所有位均为9的特殊情况这时可确定返回数组的长度和输入数组的长度相同在内部嵌套一个for循环将每一位复制过去即可执行完内部for之后可以将返回数组直接return出去。如果是特殊情况则额外写一段代码返回数组长度定义为输入数组长度1将第一位定义为1其余位定义为0即可。5.以下是力扣官方给出的答案代码1. /** 2. * Note: The returned array must be malloced, assume caller calls free(). 3. */ 4. int* plusOne(int* digits, int digitsSize, int* returnSize) { 5. // 1. 核心遍历处理末尾连续的9进位给第一个非9位加1 6. for(int idigitsSize-1;i0;i--){ 7. // 1.1 如果当前位是9加1后会进位直接置0 8. if(digits[i]9) 9. digits[i]0; 10. else{ 11. // 1.2 非9位加1完成加1操作break终止遍历无需处理前面的位 12. digits[i]; 13. break; 14. } 15. } 16. 17. // 2. 定义返回数组指针初始为NULL 18. int *resultNULL; 19. 20. // 3. 判断是否需要扩容最高位为0 → 所有位都是9如999→000 21. if(digits[0]0){ 22. // 3.1 扩容后的长度原长度1 23. *returnSizedigitsSize1; 24. // 3.2 分配扩容后的内存 25. resultmalloc(sizeof(int)*(digitsSize1)); 26. // 3.3 最高位设1进位新增的位 27. result[0]1; 28. // 3.4 复制原数组已置0的位到新数组的后续位置 29. for(int i1;idigitsSize1;i) 30. result[i]digits[i-1]; 31. } 32. else{ 33. // 4. 无需扩容返回长度为原长度 34. *returnSizedigitsSize; 35. // 4.1 分配原长度的内存 36. resultmalloc(sizeof(int)*digitsSize); 37. // 4.2 复制加1后的数组到返回数组 38. for(int i0;idigitsSize;i) 39. result[i]digits[i]; 40. } 41. 42. // 5. 返回malloc的数组符合题目要求 43. return result; 44. }有两点思想可以学习①因为出现连续进位只可能是连续999的情况所以直接遍历数组末尾看有多少个9直接替换为0到非9位停止该位1终止遍历否则就全部替换为0。②判断第一位是否为0不为0就不是特殊情况数组长度不变复制原数组即可如果为0则为特殊情况第一位置1后面都置0即可。