• 1-N中1出现的次数


    /*标记1-N中1出现的次数。例如,当N等于18时,1出现的次数为2 + 9 = 11
    个位数出现1的为:1,11,十位数出现1的为10-18*/
    public class OneNoInN {
    // 暴力解法
    public static int solution1(int num) {
    // 异常处理
    if (num < 1)
    return 0;
    // 标记变量count
    int count = 0;
    // 计算没个数中的1的个数,然后加起来,时间复杂度为O(nlogn)
    for (int i = 1; i < num + 1; i++) {
    count += get1Num(i);
    }
    return count;
    }
    public static int get1Num(int num) {
    int res = 0;
    while (num != 0) {
    if (num % 10 == 1) {
    res++;
    }
    num /= 10;
    }
    return res;
    }

    // 第二种方法,进行分析
    // 两种情况:
    // 第一种情况:最高位为1,1-114,首先划分为1-14和15-114,
    // 百位为1,则相应的对应的1的个数为num % tmp1 + 1.即114 % 100 + 1 = 15
    // 十位为1时,有 15 - 19 还有110 - 114;
    // 个位为1时,有21-91,101,111,
    // 则对应的1的个数为1 * (3 - 1) * (100 / 10)
    // 第二种情况: 最高位大于1,则最高位的情况为tmp1,其他低位的情况类似
    public static int solution2(int num) {
    // 异常处理
    if (num < 1)
    return 0;
    // 得出当前字符的长度
    int len = getLenOfNum(num);
    // 进行判断,如果当前字符长度为1,则返回1
    if (len == 1)
    return 1;
    // 记录当前最大值一个量级的一个数
    int tmp = powBase10(len - 1);
    // 得到最高位的值
    int first = num / tmp;
    int firstOneNum = first == 1 ? num % tmp + 1 : tmp;
    int otherOneNum = first * (len - 1) * (tmp / 10);
    return firstOneNum + otherOneNum + solution1(num % tmp);
    }

    // 得出当前数值的位数
    public static int getLenOfNum(int num) {
    int len = 0;
    while (num != 0) {
    len++;
    num /= 10;
    }
    return len;
    }

    // 求一个指数的值
    public static int powBase10(int base) {
    return (int) Math.pow(10, base);
    }
    public static void main(String[] args) {
    // TODO Auto-generated method stub

    }

    }

  • 相关阅读:
    第一次用NUnitAsp
    IT能够解决所有的商业问题吗?
    在这种东西里面,你会自在吗?
    看了段.net show之后的感想
    获取当前数据库中所有表的记录数
    对瀑布模型各阶段的解释
    Linux内核中的slab/slob/slub 在搞晕前先记下来
    分布式事务AT、TCC、Saga、XA 模式分析对比
    读懂Windows的“虚拟内存”为你量身定制
    示范NTFS 卷上的硬链接
  • 原文地址:https://www.cnblogs.com/Elliott-Su-Faith-change-our-life/p/7341324.html
Copyright © 2020-2023  润新知