• leetcode-258-Add Digits


    题目描述:

    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 = 111 + 1 = 2. Since 2 has only one digit, return it.

    Follow up:
    Could you do it without any loop/recursion in O(1) runtime?

     

    要完成的函数:

    int addDigits(int num) 

     

    说明:

    1、暴力解法如下,应该不难看懂:

        int addDigits(int num) 
        {
            int result;
            while(!(num>=0&&num<=9))//不是单位数的情况就进入处理
            {
                result=0;
                while(num!=0)//得到新的num
                {
                    result+=num%10;
                    num/=10;
                }
                num=result;
            }
            return num;
        }

    2、这道题目比较有意思的是,挑战能不能用O(1)的时间复杂度,也就是不用循环和递归的方法求得输出结果。

    上述代码中,外层循环是用来不断地处理数的。不让用循环,也就意味着我们必须要从数学上寻求规律。

    看一下笔者举的下述例子:

    原数 0 1 2 3 4 5 6 7 8 9
    对应的数 0 1 2 3 4 5 6 7 8 9
    原数 10 11 12 13 14 15 16 17 18 19
    对应的数 1 2 3 4 5 6 7 8 9 10/1
    原数 20 21 22 23 24 25 26 27 28 29
    对应的数 2 3 4 5 6 7 8 9 10/1 11/2

    上述从1到9为一个循环,那么是不是后续的数字也会遵循这样的规律,从而最终得到在[1,9]之间的结果呢?

    答案是肯定的。

    因为我们假设一个比较大的两位数,比如ab,其实ab的值是a*10+b,那么对应的数应该是a+b。因为a和b都是正数,那么肯定对应之后的数要小于原来的数。除非a=0,那这时候由上述表格中第一行看得很清楚。

    这样子每一个对应的数都小于原来的数,减小了9*a,那么不断地往前腾挪,最终必然到达[1,9]之间。

    那么我们由上述表格可以很直观地得到一个结论:

    假设要处理的数为n,则最终对应的数=(num-1)%9+1

    原本我们可以直接num%9,但是对于num=9或者num=18这些9的整倍数,结论不符合,略微修改一下。

    代码如下:

        int addDigits(int num) 
        {
            return 1 + (num - 1) % 9;
        }

    PS:觉得有点奇怪,2中O(1)的做法实测8ms,1中循环迭代的做法实测7ms,竟然O(1)花费时间更长……

       有同学知道原因么?

  • 相关阅读:
    1347: Last Digit (周期函数)
    1363: Count 101 (经典数位dp)
    1360: Good Serial Inc.(不知道是什么类型的题)
    C#winForm调用WebService的远程接口
    Web Service 的创建简单编码、发布和部署
    极致精简的webservice集成例子
    SVN使用教程总结
    C# int.Parse()与int.TryParse()
    C# 函数1 (函数的定义)
    C#中的委托和事件
  • 原文地址:https://www.cnblogs.com/chenjx85/p/8831996.html
Copyright © 2020-2023  润新知