数字和的运算算法剖析

来源:互联网 发布:linux 递归授权 编辑:程序博客网 时间:2024/05/22 05:23

问题详见: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 = 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?

解题思路:

      如果只是针对一个非负整数,求它的数字和,我们能很快地想到下面的算法:

int digitsum(int num) {    int sum=0;    while(num){        sum+=num%10;        num/=10;    }    return sum;}

      如果按着这条思路走的话,这里面临的问题就是要将计算出来的数字和在每次循环之前都要判断一下和是否已经超过10,所以这样的话计算复杂度就是O(n2)(n代表该非负整数的位数)的级别。在这个题目的情况下很明显复杂度太高。然后在自己想破头皮的时候发现大神竟然只用一行代码就计算出来结果!!!只用一行!!!一行!!!下面是具体算法实现:

class Solution {public:    int addDigits(int num) {        return num==0?0:(num%9==0?9:(num%9));    }};

      就这么短短的一行代码,没有循环,没有递归,而且算法复杂度真的只有O(1),在几近崩溃的同时发现该解法确实是抓住了问题的本质,因为要一直计算到非负整数的数字和是一个个位数,所以就找到了这些数字和的共同之处。我们发现一个1~8的数字在乘以10的任何次方再mod 9的时候都等于该数字本身(这是因为x = x+9x mod 9,同理x = x+99x mod 9,……)。而对0和9来说,9的所有非0倍数的数字和也都是9的整数倍,而如果非负整数是0的话其数字和就是0。所以基于代数运算性质的一个特殊方法被我们所找到。于是该问题便可以用一行代码求解。另附该算法的提交截图:
这里写图片描述

0 0
原创粉丝点击