LintCode Python解法

3.統計數字(Digit Count)git

計算數字 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))的解法,搞懂思路後,終於本身實現了markdown

本題求k出現的次數,其實能夠等價於求k在各個數位上出現的次數之和app

以n=3154爲例,分狀況討論spa

設k所在數位爲index(好比k在千位,index就是3;k在百位,index就是2)設計

設digit爲k所在數位上,n對應的數值(好比k在千位,digit就是3;k在百位,digit就是1)code

設k所在數位前的數爲高位high,k所在數位後的數爲低位low(好比k在百位,high就是3,low就是54;k在十位,high就是31,low就是4)blog

1、當k>digit時ip

  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)

2、當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

3、當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)

 4、當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

 

4. 醜數II(ugly number ii)

設計一個算法,找出只含素因子235 的第 n 小的數。

符合條件的數如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...

 

解決本題的思路是,除了1之外,題目要求的醜數只含有2,3,5這3種質因子,因此後面的醜數都是前面的醜數乘以2,3,5獲得的

原問題轉化爲求一個數列中,第n個醜數如何得到的問題

假設長度爲n-1的醜數數列第一個數爲uglys[1] = 1

設2*uglys[i] > uglys[n-1], 3*uglys[j] > uglys[n-1], 5*uglys[k] > uglys[n-1] (注意,這裏的n-1表示第n-1個數,跟列表裏的下標不同)

若是i,j,k分別是知足上述不等式的最小整數,那麼uglys[n] = min(2*uglys[i], 3*uglys[j], 5*uglys[k])

很顯然,i,j,k大多時候是不一樣的,因此咱們要設置3個下標來分別記錄他們在數組中的位置

代碼以下:

 1 class Solution:  2 """  3  @param n: An integer  4  @return: return a integer as description.  5 """  6 def nthUglyNumber(self, n):  7 uglyNumers = [1]  8  9 i2, i3, i5 = 0, 0, 0 10 num2, num3, num5 = uglyNumers[i2] * 2, \ 11 uglyNumers[i3] * 3, \ 12 uglyNumers[i5] * 5 13 # 雖然形式是雙重循環 14 # 可是裏面的3個while每次最多各執行一次 15 # 因此時間複雜度是O(n) 16 while len(uglyNumers) < n: 17 while num2 <= uglyNumers[-1]: 18 i2 += 1 19 num2 = uglyNumers[i2] * 2 20 while num3 <= uglyNumers[-1]: 21 i3 += 1 22 num3 = uglyNumers[i3] * 3 23 while num5 <= uglyNumers[-1]: 24 i5 += 1 25 num5 = uglyNumers[i5] * 5 26  uglyNumers.append(min(num2, num3, num5)) 27 return uglyNumers[-1]
相關文章
相關標籤/搜索