zoukankan      html  css  js  c++  java
  • [leetCode]剑指 Offer 43. 1~n整数中1出现的次数

    在这里插入图片描述

    递归

     直观思路是遍历每一个数字,对每一个数字采用“%”“/”的方法取个位判断是否为1然后累加。由于数字n有O(logn)为所以时间复杂度为O(nlogn)。应该考虑更快的算法。
     假设输入的数字n为21345,可以把它分为两部分:

    • 1~1345
    • 1346~21345

    先来分析1345~21345这部分。从万位开始万位出现1的次数为10000,因为可取10000 ~ 19999,1出现了10000次。剩余4位1出现的次数又是多少呢?把1345 ~ 21345 再分为两部分:

    • 1346 ~ 11345
    • 11346 ~ 21345
      由排列组合可知这两部分剩下4为每一位都可以取1,取1后剩下的3位有0~9种取法所以一共有 2 ∗ C 4 1 ∗ 1 0 3 = 8000 2 * C_4^1 * 10^3 =8000 2C41103=8000种。

    最后剩下的1~1345 可以递归求解。由于递归的次数为n的位数所以时间复杂度位O(logn)

    class Solution {
    
        public int countDigitOne(int n) {
            if(n <=  0) return 0;
            // 为方便递归计算将数字转换为字符串
            String strN = String.valueOf(n);
            return countDigitOne(strN);
        }
    
        private int countDigitOne(String strN) {
            int len = strN.length();
            if(strN == null || len == 0) 
                return 0;
            // 第一位数字
            int first = strN.charAt(0) - '0';
    
            // strN只有1位,且为0
            if(len == 1 && first == 0)
                return 0;
            // strN只有一位1只能出现1次
            if(len == 1 && first > 0)
                return 1;
            // 假设strN是21345
            // numOfFirstDigit是第一位1出现的数目:10000~19999;
            int numOfFirstDigit = 0;
            if(first > 1)
                numOfFirstDigit = powerBase10(len - 1);
            else if(first == 1)
                // 最后要+1 因为first本身为1
                numOfFirstDigit = Integer.valueOf(strN.substring(1,len)) + 1;
            // numOfOtherDigits是1346~21345中除第一位外的数位中的数目
            int numOfOtherDigits = first * (len - 1) * powerBase10(len - 2);
            // 1~1345中的数目
            int numRecursive = countDigitOne(strN.substring(1,len));
            return numOfFirstDigit + numOfOtherDigits + numRecursive;
        }
    
        // 求10的n次幂
        private int powerBase10(int n) {
            int result = 1;
            for(int i = 0; i < n; ++i) {
                result *= 10;
            }
            return result;
        }
    }
    
  • 相关阅读:
    内存泄漏 Memory Leaks 内存优化 MD
    Handler Thread 内部类引起内存泄露分析
    为什么不取消注册BroadcastReceiver会导致内存泄漏
    WebChromeClient 简介 API 案例
    WebViewClient 简介 API 案例
    java.net.URI 简介 文档 API
    android.net.Uri 简介 API
    RV 多样式 MultiType 聊天界面 消息类型 MD
    JS函数声明与定义,作用域,函数声明与表达式的区别
    CSS中table tr:nth-child(even)改变tr背景颜色: IE7,8无效
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13859948.html
Copyright © 2011-2022 走看看