丑数是唯一素数为2、3或5的数。序列1、2、3、4、5、6、8、9、10、12、15…显示前11个丑数。按照惯例,其中包括1。
给定数字n,任务是查找第n个丑数。
输入:n = 7
输出8
输入:n = 10
输出:12
输入:n = 15
输出:24
输入:n = 150
输出:5832
方法1(简单)
对所有正整数循环,直到一个丑陋的数字小于n(如果一个整数丑陋而不是递增的丑陋数字计数)。
要检查数字是否丑陋,请将该数字除以2、3和5的最大可除幂。如果数字变为1,则它是丑陋的数字,否则不是。
例如,让我们看看如何检查300是否丑陋。2的最大可乘幂是4,将300除以4后得到75。3的最大可乘幂是3,将75除以3后得到25。5的最大可乘幂是25,将25除以25后得到1由于我们最终得到1,所以300是丑数。
下面是上述方法的实现:
# Python3 code to find nth ugly number
# This function divides a by greatest
# divisible power of b
def maxDivide(a, b):
while a % b == 0:
a = a / b
return a
# Function to check if a number
# is ugly or not
def isUgly(no):
no = maxDivide(no, 2)
no = maxDivide(no, 3)
no = maxDivide(no, 5)
return 1 if no == 1 else 0
# Function to get the nth ugly number
def getNthUglyNo(n):
i = 1
# ugly number count
count = 1
# Check for all integers untill
# ugly count becomes n
while n > count:
i += 1
if isUgly(i):
count += 1
return i
# Driver code
no = getNthUglyNo(150)
print("150th ugly no. is ", no)
Output
150th ugly no. is 5832
此方法效率不高,因为它会检查所有整数,直到丑陋的数字计数变为n.
方法2(使用动态规划)
这是具有O(n)额外空间的省时解决方案。丑数序列是1、2、3、4、5、6、8、9、10、12、15…,
因为每个数字只能除以2、3、5,这是查看序列的一种方法将序列分为以下三组:
(1)1×2、2×2、3×2、4×2、5×2,…
(2)1×3、2×3、3×3, 4×3、5×3,…
(3)1×5、2×5、3×5、4×5、5×5,…
我们可以发现每个子序列都是丑序列本身(1、2、3、4、5,…)乘以2、3、5。然后我们使用类似的合并方法作为合并排序,从三个序列中获取每个丑数子序列。每一步我们都选择最小的一步,然后再向前迈一步。
1 Declare an array for ugly numbers: ugly[n]
2 Initialize first ugly no: ugly[0] = 1
3 Initialize three array index variables i2, i3, i5 to point to
1st element of the ugly array:
i2 = i3 = i5 =0;
4 Initialize 3 choices for the next ugly no:
next_mulitple_of_2 = ugly[i2]*2;
next_mulitple_of_3 = ugly[i3]*3
next_mulitple_of_5 = ugly[i5]*5;
5 Now go in a loop to fill all ugly numbers till 150:
For (i = 1; i < 150; i++ )
{
/* These small steps are not optimized for good
readability. Will optimize them in C program */
next_ugly_no = Min(next_mulitple_of_2,
next_mulitple_of_3,
next_mulitple_of_5);
ugly[i] = next_ugly_no
if (next_ugly_no == next_mulitple_of_2)
{
i2 = i2 + 1;
next_mulitple_of_2 = ugly[i2]*2;
}
if (next_ugly_no == next_mulitple_of_3)
{
i3 = i3 + 1;
next_mulitple_of_3 = ugly[i3]*3;
}
if (next_ugly_no == next_mulitple_of_5)
{
i5 = i5 + 1;
next_mulitple_of_5 = ugly[i5]*5;
}
}/* end of for loop */
6.return next_ugly_no
Example:
initialize
ugly[] = | 1 |
i2 = i3 = i5 = 0;
First iteration
ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(2, 3, 5)
= 2
ugly[] = | 1 | 2 |
i2 = 1, i3 = i5 = 0 (i2 got incremented )
Second iteration
ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 3, 5)
= 3
ugly[] = | 1 | 2 | 3 |
i2 = 1, i3 = 1, i5 = 0 (i3 got incremented )
Third iteration
ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 6, 5)
= 4
ugly[] = | 1 | 2 | 3 | 4 |
i2 = 2, i3 = 1, i5 = 0 (i2 got incremented )
Fourth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 5)
= 5
ugly[] = | 1 | 2 | 3 | 4 | 5 |
i2 = 2, i3 = 1, i5 = 1 (i5 got incremented )
Fifth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 10)
= 6
ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 |
i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented )
Will continue same way till I < 150
# Python program to find n'th Ugly number
# Function to get the nth ugly number
def getNthUglyNo(n):
ugly = [0] * n # To store ugly numbers
# 1 is the first ugly number
ugly[0] = 1
# i2, i3, i5 will indicate indices for
# 2,3,5 respectively
i2 = i3 = i5 = 0
# Set initial multiple value
next_multiple_of_2 = 2
next_multiple_of_3 = 3
next_multiple_of_5 = 5
# Start loop to find value from
# ugly[1] to ugly[n]
for l in range(1, n):
# Shoose the min value of all
# available multiples
ugly[l] = min(next_multiple_of_2,
next_multiple_of_3,
next_multiple_of_5)
# Increment the value of index accordingly
if ugly[l] == next_multiple_of_2:
i2 += 1
next_multiple_of_2 = ugly[i2] * 2
if ugly[l] == next_multiple_of_3:
i3 += 1
next_multiple_of_3 = ugly[i3] * 3
if ugly[l] == next_multiple_of_5:
i5 += 1
next_multiple_of_5 = ugly[i5] * 5
# Return ugly[n] value
return ugly[-1]
# Driver Code
def main():
n = 150
print getNthUglyNo(n)
if __name__ == '__main__':
main()
Output
5832
此题的关键是找到丑数的规律。