题目
有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。
示例:
输入: k = 5
输出: 9
分析: 对所有因子只能为3,5,7的数字进行排序,找到第k位,暴力解法是对此前出现的所有的数都与3,5,7相乘,找到大于k-1位且最小的那个数即为第k位数,动态规划暴力枚举,见方法1
方法1: dp暴力解法,时间复杂度
O
(
n
2
)
O(n^2)
O(n2)
class Solution:
def getKthMagicNumber(self, k: int) -> int:
dp = [0]*k
dp[0] = 1
for i in range(1, k):
dp[i] = dp[i-1] * 9
for j in range(i):
for m in (3,5,7,9):
result = dp[j]*m
if result > dp[i-1]:
dp[i] = min(dp[i], result)
return dp[k-1]
方法2: 找规律,优化dp算法,dp存储对应位置的数,通过创建三个指针,每一个指针指向dp的数只固定乘以[3, 5, 7]中固定的一位,比如三个指针a3, b5, c7对应只乘以3, 5, 7, 三个指针乘积最小的那个数就是下一个数,同时,对应指针往后移动一位,比如,初始情况a3=0, b5=0, c7=0, 乘积分别为3, 5, 7, 则dp[1]=3, 此时a3指针后移一位,a3=1, 当再次相乘时,乘积分别为9, 5, 7, 此时dp[2]=5, b5后移一位, b5=1, 以此类推, 时间复杂度为 O ( n ) O(n) O(n)
class Solution:
def getKthMagicNumber(self, k: int) -> int:
dp = [0]*k
dp[0] = 1
a3=0; b5=0; c7=0
for i in range(1, k):
r3 = dp[a3]*3
r5 = dp[b5]*5
r7 = dp[c7]*7
result = min(r3, r5, r7)
dp[i] = result
if result == r3:
a3 += 1
if result == r5:
b5 += 1
if result == r7:
c7 += 1
return dp[-1]