问题描述
- 本题是力扣中难度不算大的题目。
- 一排房屋,内部可偷物品价值各不同,如何选取、才能使小偷一晚工作价值最大化?
前提: 小偷知道每一家的价值,任何家门都可以打开
约束条件:小偷不能连续偷隔壁房的,否则触发报警。
解法大多数用推衍万能公式的方法解决。我们尝试用不同的思路。
方案思考
- 一般来说能够偷最大的房间数的话,单双数一旦选择就不变化;
- 只要房间单双数有变化(不全偷单或者双数的房间),最终就会就少偷一个房间;
- 试着将单双数分别来看,建立 [位置,价值] 数组;
- 从全局最高(单双皆可)开始偷;
- 判断偷与不偷,就看左右是否已被偷过即可。
代码实现函数
def index_house():
# 给每个房子编号,(1, len(list)+1),与感官单双一致即可
# 对数组进行价值排序:降序
pass
def take_max():
# 从全局最高价值的房子先偷
# 然后通过判断是否偷次高价值的房子,如不行就continue
# 按顺序偷完所有的高价值房子
pass
编码完成
from operator import itemgetter
def index_house(nums):
# 创建带编号和价值的房间空列表
houses = []
# 给每个房子编号,(1, len(list)+1),与感官单双一致即可
for i in range(1, len(nums)+1):
houses.append([i, nums[i-1]])
# 对数组进行价值排序:降序
houses.sort(key = itemgetter(1), reverse = True)
return houses
houses = index_house(nums)
def take_max():
# 创建已偷房间号列表
stolen_index = []
# 创建已偷初始价值为0单位
value = 0
# 从全局最高价值的房子先偷
# 然后通过steal_or_not()判断是否偷次高价值的房子,如不行就continue
# 按顺序偷完所有的高价值房子
for i in houses:
if i[0]+1 in stolen_index or i[0]-1 in stolen_index or i[0] in stolen_index:
continue
else:
stolen_index.append(i[0])
value += i[1]
return stolen_index, value
stolen_index, value = take_max()
n = len(stolen_index)
print('贼最多偷{}间房子,最优获得价值{}单位'.format(n, value))
测试
nums = = [2, 1, 1, 2]
结果:
# stolen_index = [1, 4]
# value = 4
贼最多偷2间房子,最优获得价值4单位
nums = [3, 3, 2, 1, 1, 2, 1, 3, 2, 1, 1]
结果:
# stolen_index = [1, 8, 3, 6, 10]
# value = 11
贼最多偷5间房子,最优获得价值11单位