leetcode hard模式专杀之233. Number of Digit One

来源:互联网 发布:centos中文输入法切换 编辑:程序博客网 时间:2024/06/05 09:36

这道题思路很快就有了,但提交了七八次才通过,总结下来,是自己对数字计算可能还是不够敏感,导致边界条件总是考虑不周,不过总算独立完成了,足够犒赏自己一笔钱了,嘿嘿。思路如下:比如有一个数123, 可以这样计算,设定个位数为1,满足条件的其他位数上的组合有n0个,再假设十位数上的数字是1,满足条件的其他位数上的组合有n1个,再假设百位上的数字位1,满足条件的其他位数上的组合为n3,则最终的结果为n1+n2+n3,那么问题来了,怎么求满足条件的组合数呢?这就是这个问题的复杂性了,经过仔细考虑和试错,有三种情况要考虑,第一种第k位上的数字本身就>1,第二种==1,第三种<1,分三种情况讨论即可。然后还要注意各位数的情况。计算组合数的时候,尽量用整数运算,而不要用什么字符串遍历,否则时间复杂度是过不去的。不废话了,上代码:


public class Solution {    public int minusOneAt(int num, int position){return num-(int)Math.pow(10, position);}public int strip(int num, int position){int tenth = (int)Math.pow(10, position);if((num/(int)Math.pow(10, position))%10 > 1){if(position == 0){return num/10;}//return (num/(tenth*10))*10+num%tenth;return ((num/tenth)/10)*tenth+(int)Math.pow(10, position)-1;}else if((num/(int)Math.pow(10, position))%10 == 1){if(position == 0){return num/10;}return ((num/tenth)/10)*tenth+num%tenth;}else{int newNum = minusOneAt(num, position);if(position == 0){return newNum/10;}return ((newNum/tenth)/10)*tenth+(int)Math.pow(10, position)-1;}}    public int countDigitOne(int n) {    int num = n;        int digitCnt = 0;        while(num>0){        digitCnt+=1;        num = num/10;        }        int result = 0;        for(int i = 0; i < digitCnt; i++){        int afterStrip = strip(n, i);        result += afterStrip+1;        }        return result;    }}