LeetCode题解(1449):数位成本和为目标值的最大数字(Python)
发布日期:2021-06-29 19:58:41
浏览次数:3
分类:技术文章
本文共 3705 字,大约阅读时间需要 12 分钟。
题目:(困难)
标签:字符串、动态规划
解法 | 时间复杂度 | 空间复杂度 | 执行用时 |
---|---|---|---|
Ans 1 (Python) | O ( 9 N ) O(9^N) O(9N) : 其中N为最长可能结果的位数 | O ( N ) O(N) O(N) | 超出时间限制 |
Ans 2 (Python) | O ( T ) O(T) O(T) : 其中T为target的值 | O ( T ) O(T) O(T) | 420ms (43.94%) |
Ans 3 (Python) | O ( T ) O(T) O(T) : 其中T为target的值 | O ( T ) O(T) O(T) | 224ms (92.94%) |
解法一(异常暴力到难以想象的回溯算法):
class Solution: def largestNumber(self, cost: List[int], target: int) -> str: # 排序的所有成本选择 ordered_cost = list(sorted(set(cost))) N = len(ordered_cost) # 回溯算法计算最多位数的选择 length = target // ordered_cost[0] # 最大可能位数 lst = [0] * length # 当前成本列表 now = ordered_cost[0] * length # 当前总成本 maybe_lst = [] while True: # 如果等于目标结果,则提取目标结果 if now == target: maybe_lst.append(tuple(lst)) # 继续完成回溯算法 this_idx = lst.pop() # 当前被替换对象 next_idx = this_idx + 1 now -= ordered_cost[this_idx] # 如果当前最后一位可以被替换为更大的且不超过target,则替换最后一位 if next_idx < N and now + ordered_cost[next_idx] <= target: num = (target - now) // ordered_cost[next_idx] lst += [next_idx] * num now += ordered_cost[next_idx] * num # 如果当前最后一位不能被替换为更大的且不超过target,则替换前一位 elif lst: this_idx = lst.pop() # 当前被替换对象 now -= ordered_cost[this_idx] next_idx = this_idx + 1 if next_idx < N and now + ordered_cost[next_idx] <= target: num = (target - now) // ordered_cost[next_idx] lst += [next_idx] * num now += ordered_cost[next_idx] * num # 如果已回溯到开头 else: break # 如果没有回溯到结果则返回"0" if not maybe_lst: return "0" # 生成成本和最大数字的对应表 cost_dict = { } for i, ch in enumerate(reversed(cost)): if ch not in cost_dict: cost_dict[ch] = 9 - i # 生成所有可能的结果 ans = [] for elem in maybe_lst: maybe_ans = [cost_dict[ordered_cost[elem]] for elem in elem] maybe_ans = int("".join([str(elem) for elem in sorted(maybe_ans, reverse=True)])) ans.append(maybe_ans) return str(max(ans))
解法二(动态规划):
class Solution: def largestNumber(self, cost: List[int], target: int) -> str: # 生成状态列表 dp = [tuple()] * (target + 1) dp[0] = (0,) # 生成成本和最大数字的对应表 cost_dict = { } for i, ch in enumerate(reversed(cost)): if ch not in cost_dict: cost_dict[ch] = 9 - i # 计算状态列表 for i in range(1, target + 1): maybe_lst = [] for c in cost_dict: idx = i - c if idx >= 0 and dp[idx]: maybe_lst.append(dp[idx] + (cost_dict[c],)) if maybe_lst: dp[i] = max(maybe_lst, key=lambda x: (len(x), x)) # 返回结果 return "".join([str(elem) for elem in dp[-1][1:]]) if dp[-1] else "0"
解法三(优化解法二):
使用字符串替换元组
class Solution: def largestNumber(self, cost: List[int], target: int) -> str: # 生成状态列表 dp = [""] * (target + 1) dp[0] = "0" # 生成成本和最大数字的对应表 cost_dict = { } for i, ch in enumerate(reversed(cost)): if ch not in cost_dict: cost_dict[ch] = str(9 - i) # 计算状态列表 for i in range(1, target + 1): maybe_lst = [] for c in cost_dict: idx = i - c if idx >= 0 and dp[idx]: maybe_lst.append(dp[idx] + cost_dict[c]) if maybe_lst: dp[i] = max(maybe_lst, key=lambda x: (len(x), x)) # 返回结果 return dp[-1][1:] if dp[-1] else "0"
转载地址:https://dataartist.blog.csdn.net/article/details/108283721 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2024年04月27日 17时19分00秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
编译和链接的过程
2019-04-30
Git学习(二):git-rev-parse命令初识
2019-04-30
vim字符串替换
2019-04-30
C语言:堆和栈的区别是什么?
2019-04-30
C语言:二级指针(指向指针的指针)详解
2019-04-30
C语言:断言assert函数完全攻略
2019-04-30
C语言:命令行选项解析函数---getopt()和getopt_long()
2019-04-30
C语言:inline,static inline
2019-04-30
Git学习(三):Git 撤销commit文件 和 回退push的文件
2019-04-30
WAV系列之一:G711编解码原理及代码实现
2019-04-30
WAV系列之二:ADPCM编解码原理及代码实现
2019-04-30
详解shell中source、sh、bash、./执行脚本的区别
2019-04-30
Git学习(四):git clean的用法
2019-04-30
Linux命令(一): ln - 创建和删除软、硬链接
2019-04-30
C语言:static关键字的作用
2019-04-30
C语言:volatile关键字的作用
2019-04-30
/usr/bin/ld: skipping incompatible解决方案
2019-04-30
Gstreamer学习笔记(8):Gobject类对象
2019-04-30