第二次做leetcode中的难度为easy的题-258

来源:互联网 发布:淘宝基础店铺全屏店招 编辑:程序博客网 时间:2024/05/22 15:34

今天做的仍然是难度为easy的题,昨天晚上和大卓哥讨论的时候,他一直在说我眼高手低,总觉得解决问题“不就是那样嘛”,但是真正写代码的时候会发现自己的想法不够全面,有时候体现在代码编译不通、有时候又是算法没想好或者根本想的不对。leetcode是一个很好地平台,因为这里可以提供很多有意思的题目,也会检查你写的代码对不对。

题目:

Add Digits
Total Accepted: 45239 Total Submissions: 95297 Difficulty: Easy
Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.
For example:
Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.
Follow up:
Could you do it without any loop/recursion in O(1) runtime?
Hint:
A naive implementation of the above process is trivial. Could you come up with other methods?
What are all the possible results?
How do they occur, periodically or randomly?
You may find this Wikipedia article useful.https://en.wikipedia.org/wiki/Digital_root

分析:如果不考虑时间复杂度,我想到的算法如下:

AD1:提取这个整数每个数位上的数字--取模、除以10-再取除以10。直到除以10的结果为0。(用到循环)

AD2:讲各个数位上的数相加,如果小于10,则直接返回。否则,相加得到的这个数用到AD1中。()

public static int DigitalRoot(int n){
int m=0;
while(n!=0){
m=m+n%10;
n=n/10;
}
if (m<10){
return m;
}else{
return DigitalRoot(m);//递归
}
 
}

考虑时间复杂度的话,就要考虑Digital Root的性质,这里有三条性质比较重要:

1.一个数的数根加9等于这个数的数根;

2.一个数乘以9之后的数根为9;(说明如果一个数是9的倍数,那么它的根为9)

3.\mathit{dr}(a+b) \equiv \mathit{dr}(\mathit{dr}(a)+\mathit{dr}(b) ).

4.\mathit{dr}(a \times b) \equiv \mathit{dr}(\mathit{dr}(a)\times\mathit{dr}(b) ).

所以,一个数可以看成是数根以及9的倍数之和,即dr(r+9*i)=dr(r)+dr(9*i)=dr(n)+dr(9)=r(r<9);

public class Solution {
    public int addDigits(int n) {
        if(n%9>0||n==0){ //注意边界
            return n%9;
        }else{
            return 9;
        }
    }
}

或者直接用wikipedia的方法:

public class Solution {
    public int addDigits(int n) {
        return n-9*((n-1)/9);
    }
}

总结:用Wikipedia方法比较巧妙,时间复杂度上很占优势,但是或者需要我们有在短时间内找出潜在规律的能力,或者需要我们的一些经验知识。用普通的递归方法时间复杂度较高。

0 0