LeetCode66、加一

58 阅读1分钟

LeetCode 系列记录我学习算法的过程。

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

题目

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例:

输入: digits = [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。


输入: digits = [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。


输入: digits = [0]
输出: [1]

提示

  • 1 <= digits.length <= 100
  • 0 <= digits[i] <= 9

思路

题目的意思是相当于是让我们将数组看成一个非负整数,然后对其加一,将结果返回即可

这里的重点就在于进位,即加一后满 10 要向前进位,这在给出的例子中没有体现,导致一开始没有想到这个点

  • 定义 p 记录当前项是否需要进位
  • 从后往前对字符串 digits 进行遍历
  • 定义 n 记录当前项加一后的值
  • 判断 n 是否大于 9,大于则需要进位,并将当前项赋值为 0
  • 反之则无需进位,将 n 赋值给当前项即可
  • 最后遍历完再判断是否还有进位未处理,有则在数组开头插入 1
  • 将处理好后的数组返回

代码实现

/**
 * @param {number[]} digits
 * @return {number[]}
 */
var plusOne = function(digits) {
    // 记录当前位是否需要进位
    let p = false
    // 从后往前遍历数组
    for(let i = digits.length - 1; i >= 0; i--) {
        // 记录当前项 + 1 的值 n
        let n = digits[i] + 1
        // 如果 n > 0,则需要进位,并将当前位置0
        if (n > 9) {
            digits[i] = 0
            p = true
        } else {
            // 反之则将 n 赋值当前位,无需进位,跳出循环
            digits[i] = n
            p = false
            break
        }
    }
    // 遍历结束还需进位,则在数组第一项插入 1
    if (p) {
        digits.unshift(1)
    }
    // 返回处理后的数组
    return digits
};

image.png

优化

需要进位的都是 9,且进位后都是赋值为 0,那么也可以借助这个规律,从后往前找到第一个不为 9 的数组项,将其加一,然后将后面所有项都赋值为 0 即可:

var plusOne = function(digits) {
    const n = digits.length
    for (let i = n - 1; i >= 0; --i) {
        // 当前项不为 9,直接加一,然后将后面所有项赋值为0
        if (digits[i] !== 9) {
            digits[i]++
            for (let j = i + 1; j < n; ++j) {
                digits[j] = 0
            }
            return digits
        }
    }

    // digits 中所有的元素均为 9,则将所有项赋值 0,第一项赋值 1
    const ans = new Array(n + 1).fill(0)
    ans[0] = 1
    return ans
};

image.png