LintCode Python解法

3.统计数字(Digit Count)

计算数字 k 在 0 到 n 中的出现的次数,k 可能是 0~9 的一个值。

首先是,惯用思维,2个循环解决,这样做的时间复杂度为O(n*2)

 1 class Solution:
 2     """
 3     @param k: An integer
 4     @param n: An integer
 5     @return: An integer denote the count of digit k in 1..n
 6     """
 7     def digitCounts(self, k, n):
 8         # write your code here
 9         times = 0
10
11         for i in range(n+1):
12             item = str(i)
13             while len(item) > 0:
14                 if item[0:1] == str(k):
15                     times += 1
16                 item = item[1:]
17         return times

提交成功后,看到讨论区有时间复杂度为O(log(n))的解法,搞懂思路后,终于自己实现了

本题求k出现的次数,其实可以等价于求k在各个数位上出现的次数之和

以n=3154为例,分情况讨论

设k所在数位为index(比如k在千位,index就是3;k在百位,index就是2)

设digit为k所在数位上,n对应的数值(比如k在千位,digit就是3;k在百位,digit就是1)

设k所在数位前的数为高位high,k所在数位后的数为低位low(比如k在百位,high就是3,low就是54;k在十位,high就是31,low就是4)

一、当k>digit时

  1.k在个位:(000~314)k  high=315  index=0

  共有315*1 = high*(10^index) = 315种可能

  2.k在十位:(00~30)k(0~9)  high=31  index=1

  共31*10 = high*(10^index) = 310种可能

  3.k在百位:(0~2)k(00~99)  high=3  index=2

  共3*100 = high*(10^index) = 300种可能

  4.k在千位  high=0  index=3

  共有0*1000 = high*(10^index) = 0种可能

  所以,当k>digit时,k出现次数为high*(10^index)

二、当k=digit时

  1.k在个位:(000~315)k  high=315  low=0  index=0

  共有316 = 315*10^0+0+1 = high*(10^index)+low+1 = 316种可能

  2.k在十位:(00~30)k(0~9)+31k(0~4)  high=31  low=4  index=1

  共31*10+5 = 31*10^1+4+1 = high*(10^index)+low+1 = 315种可能

  3.k在百位:(0~2)k(00~99)+3k(00~54)  high=3  low=54  index=2

  共3*100+55 = 3*10^2+54+1 = high*(10^index)+low+1 = 355种可能

  4.k在千位:k(000~154)  high=0  low=154  index=3

  共0*1000+155 = 0*10^3+154+1 = high*(10^index)+low+1 = 155种可能

  所以,当k>digit时,k出现次数为high*(10^index)+low+1

三、当k<digit时

  1.k在个位:(000~315)k  high=315  index=0

  共有316*1 = (315+1)*(10^0) = (hith+1)*(10^index) = 316种可能

  2.k在十位:(00~31)k(0~9)  high=31  index=1

  共32*10+10 = (31+1)*(10^1) = (hith+1)*(10^index) = 320种可能

  3.k在百位:(0~3)k(00~99)  high=3  index=2

  共4*(10^2) = (3+1)*(10^2) = (hith+1)*(10^index) = 400种可能

  4.k在千位:k(000~999)  high=0  index=3

  共1*(10^3) = (0+1)*(10^3) = (hith+1)*(10^index) = 1000种可能

  所以,当k<digit时,k出现次数为(hith+1)*(10^index)

四、当k=0时

  由于没有0xxx,00xx,000x这种数字,

  所以k=0时,在千位就比k等于其他数字少了1000次,在百位少100次,在十位少10次,

  在个位时0000即为0,所以不比k等于其他数字时少

  代码如下:

 1 class Solution:
 2     """
 3     @param: : An integer
 4     @param: : An integer
 5     @return: An integer denote the count of digit k in 1..n
 6     """
 7
 8     def digitCounts(self, k, n):
 9         # k出现的次数
10         times = 0
11
12         quotient = n
13         # 将整数转为字符串后,利用 len() 判断 n 的位数
14         # i即为分析中的index
15         for i in range(len(str(n))):
16             # remainder 即为分析中的digit
17             remainder = quotient % 10
18             # 获得高位high
19             quotient = quotient // 10
20             power = pow(10, i)
21
22             if k > remainder:
23                 times += quotient * power
24             elif k == remainder:
25                 # 通过高位乘以10对应的(幂+1)
26                 # 加上 digit乘以10对应的幂
27                 # 获得与低位互补的新的高位
28                 # 再用n减去新的高位,即可获得低位
29                 new_quotient = quotient * power * 10 30                                + remainder * power
31                 times += (quotient * power 32                           + (n - new_quotient) 33                           + 1)
34             else:
35                 times += (quotient + 1) * power
36
37             if k == 0:
38                 # 当k不在个位时,k出现次数要减去10对应的幂
39                 if power != 1:
40                     times -= power
41
42         return times

原文地址:https://www.cnblogs.com/longchaos/p/10424882.html

时间: 2024-11-12 09:21:56

LintCode Python解法的相关文章

FizzBuzzWhizz问题python解法

FizzBuzzWhizz 你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏.此时有100名学生在上课.游戏的规则是: 1. 你首先说出三个不同的特殊数,要求必须是个位数,比方3.5.7. 2. 让全部学生拍成一队,然后按顺序报数. 3. 学生报数时,假设所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz:假设所报数字是第二个特殊数(5)的倍数,那么要说Buzz:假设所报数字是第三个特殊数(7)的倍数,那么要说Whizz. 4. 学生报数时,假设所报数字同一时候

LintCode Python 简单级题目 最小子数组和、最大子数组和

题目1 最小子数组 描述: 给定一个整数数组,找到一个具有最小和的子数组.返回其最小和. 注意事项 子数组最少包含一个数字 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组[1, -1, -2, 1],返回 -3 标签 LintCode 版权所有 子数组 贪心 数组 题目2 最大子数组 描述: 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和. 注意事项 子数组最少包含一个数 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组[?2,2,?3,4,?1,2,1,?5,

LintCode Python 简单级题目 451.两两交换链表中的节点

题目描述: 给一个链表,两两交换其中的节点,然后返回交换后的链表. 您在真实的面试中是否遇到过这个题? Yes 样例 给出 1->2->3->4, 你应该返回的链表是 2->1->4->3. 挑战 你的算法只能使用常数的额外空间,并且不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 标签 链表 题目分析: 你的算法只能使用常数的额外空间,即不能新建链表: 并且不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 创建三个指针: head指向开始交换的

LintCode Python 入门级题目 斐波纳契数列

原题描述: 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ... 题目分析: 开始的想法,通过递归实现输出fib(n-1)+fib(n-2)的值计算,原理正确,算法复杂度高,导致运行时间超过lintcode限制: class Solution: # @param n: an integer # @retur

PAT 1084 外观数列python解法

外观数列是指具有以下特点的整数序列:d, d1, d111, d113, d11231, d112213111, ...它从不等于 1 的数字 d 开始,序列的第 n+1 项是对第 n 项的描述.比如第 2 项表示第 1 项有 1 个 d,所以就是 d1:第 2 项是 1 个 d(对应 d1)和 1 个 1(对应 11),所以第 3 项就是 d111.又比如第 4 项是 d113,其描述就是 1 个 d,2 个 1,1 个 3,所以下一项就是 d11231.当然这个定义对 d = 1 也成立.本

LeetCode算法题python解法:24. Swap Nodes in Pairs

原题: Given a linked list, swap every two adjacent nodes and return its head. Example: Given 1->2->3->4, you should return the list as 2->1->4->3. Note: Your algorithm should use only constant extra space. You may not modify the values in

文本中剔除标点符号的纯python解法

punct = set(u''':!),.:;?]}¢'"..〉>」』]]]〞︰︱︳﹐?﹒ ﹔﹕﹖﹗﹚﹜﹞!),.::?|}︴︶︸︺︼︾﹀﹂﹄﹏?-¢ 々|?·ˇˉ―--′'"([{£¥'"‵〈<「『[[[([{£¥〝︵︷︹︻ ︽︿﹁﹃﹙﹛﹝({"'--_-''') # 对str/unicode filterpunt = lambda s: ''.join(filter(lambda x: x not in punct, s)) # 对list filt

leetcode Interleaving String python 解法

Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example,Given:s1 = "aabcc",s2 = "dbbca", When s3 = "aadbbcbcac", return true.When s3 = "aadbbbaccc", return false. 方案1:DFS class Solu

LintCode Python 简单级题目 423.有效的括号序列

题目描述: 给定一个字符串所表示的括号序列,包含以下字符: '(', ')', '{', '}', '[' and ']', 判定是否是有效的括号序列. 您在真实的面试中是否遇到过这个题? Yes 样例 括号必须依照 "()" 顺序表示, "()[]{}" 是有效的括号,但 "([)]"则是无效的括号. 标签 栈 谷歌 题目分析: 循环字符串,遇左括号入栈. 遇右括号,从栈顶取元素然后配对,判断配对结果. 最后再判断栈是否不为空. 源码: cla