leetcode
leetcode 201 ~ 250
各位相加

各位相加

难度:

标签:

题目描述

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。

 

示例 1:

输入: num = 38
输出: 2 
解释: 各位相加的过程为38 --> 3 + 8 --> 11
11 --> 1 + 1 --> 2
由于 2 是一位数,所以返回 2。

示例 2:

输入: num = 0
输出: 0

 

提示:

  • 0 <= num <= 231 - 1

 

进阶:你可以不使用循环或者递归,在 O(1) 时间复杂度内解决这个问题吗?

代码结果

运行时间: 20 ms, 内存: 16.0 MB


// Java solution using Java Streams for a more functional approach
// This solution uses Java Streams to sum the digits
// Time complexity is O(log(num)) due to the number of digits
// Space complexity is O(1)
 
import java.util.stream.Stream;
 
public class Solution {
    public int addDigits(int num) {
        while (num >= 10) {
            num = Stream.of(String.valueOf(num).split(""))
                         .mapToInt(Integer::parseInt)
                         .sum();
        }
        return num;
    }
}

解释

方法:

这个题解采用了递归的思路。首先将整数转为字符串,然后遍历字符串的每一位,将其转为整数并累加到变量sum中。如果sum小于10,说明已经得到一位数,直接返回sum;否则递归调用addDigits函数,将sum作为新的输入,继续执行各位相加的操作,直到得到一位数为止。

时间复杂度:

O(n * logn)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在这个问题中选择使用递归而不是迭代进行各位相加的操作?
递归方法提供了一个直观和简洁的解决方案,允许我们以较少的代码行数实现功能。递归通常在逻辑上更容易理解和实现,特别是对于那些在逻辑上自然递归的问题。在本题中,每次递归调用都是在处理上一步的输出,直到达到结果满足特定条件(即变为一位数),这种自然的递归结构使得代码更易于理解。尽管迭代可能在某些情况下更高效,但递归在这里提供了清晰的逻辑流。
🦆
递归方法中,如果输入的数字非常大,递归深度是否会影响性能或导致栈溢出的风险?
是的,递归方法中如果输入数字非常大,递归深度可能会增加,从而影响性能和消耗更多的栈空间。在极端情况下,过深的递归可能导致栈溢出错误。然而,对于本题而言,由于每次递归调用都大幅度减少数字的位数,递归深度实际上受到位数减少的速度制约,通常不会达到导致栈溢出的层次。
🦆
该递归解法是否考虑了所有输入的边界情况,尤其是当输入为最小值0和最大可能值时的表现?
是的,该递归解法考虑了输入为0的情况,直接返回0作为结果,因为0的各位之和仍然是0。至于最大可能值,由于Python的整数类型是动态大小的,理论上可以处理任意大小的整数,递归方法同样适用。每次递归都会将输入的位数减少,最终将达到一位数,因此递归解法可以有效处理从最小到最大可能值的所有输入。
🦆
在将数字转换为字符串并遍历的过程中,是否存在更优的方法直接通过数学运算来处理,以减少字符串操作的开销?
是的,存在通过直接数学运算的方法来处理这个问题,称为数字根或模数运算。可以通过对数字执行模9的操作得到相同的结果,具体方法是:如果一个数是9的倍数且不是0,则各位相加的结果为9;否则,结果为该数模9的余数。这种方法不需要将数字转换为字符串,可以直接通过数学运算得到结果,从而减少了字符串操作的开销,提高了执行效率。

相关问题

快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n快乐数 就返回 true ;不是,则返回 false

 

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

输入:n = 2
输出:false

 

提示:

  • 1 <= n <= 231 - 1

最小元素各数位之和

最小元素各数位之和