406.根据身高重建队列
# 假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高
# 为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。
# 请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性
# (queue[0] 是排在队列前面的人)。
#
# 示例 1:
# 输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
# 输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
# 解释:
# 编号为 0 的人身高为 5 ,没有身高更高或者相同的人排在他前面。
# 编号为 1 的人身高为 7 ,没有身高更高或者相同的人排在他前面。
# 编号为 2 的人身高为 5 ,有 2 个身高更高或者相同的人排在他前面,即编号为 0 和 1 的人。
# 编号为 3 的人身高为 6 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
# 编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。
# 编号为 5 的人身高为 7 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
# 因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。
# 示例 2:
# 输入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
# 输出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]
class Solution:
def reconstructQueue(self, people):
# 卡哥的题解没拎明白,看了下Michelle的视频,思路通了,试试
res = []
size = len(people)
# 这里感觉python有点讨巧,这个sort,直接前一个元素降序排列,后一个元素升序排列
people.sort(key=lambda x:[x[0],-x[1]],reverse=True)
for p in range(size):
k = people[p][1]
# 身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点
res.insert(k,people[p])
return res
# 后续插入的数组因为身高会逐渐变矮,不影响之前插入数据的排序
# 插入的过程:
# 插入[7,0]:[[7,0]]
# 插入[7,1]:[[7,0],[7,1]]
# 插入[6,1]:[[7,0],[6,1],[7,1]]
# 插入[5,0]:[[5,0],[7,0],[6,1],[7,1]]
# 插入[5,2]:[[5,0],[7,0],[5,2],[6,1],[7,1]]
# 插入[4,4]:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
if __name__ == '__main__':
people = [[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]
# people.sort(key=lambda x:[x[0],-x[1]],reverse=True)
# print(people)
tmp = Solution()
res = tmp.reconstructQueue(people)
print(res)
452. 用最少数量的箭引爆气球
# 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart
# 和 xend之间的气球。你不知道气球的确切 y 坐标。
# 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足
# xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
# 给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。
#
# 示例 1:
# 输入:points = [[10,16],[2,8],[1,6],[7,12]]
# 输出:2
# 解释:气球可以用2支箭来爆破:
# -在x = 6处射出箭,击破气球[2,8]和[1,6]。
# -在x = 11处发射箭,击破气球[10,16]和[7,12]。
#
# 示例 2:
# 输入:points = [[1,2],[3,4],[5,6],[7,8]]
# 输出:4
# 解释:每个气球需要射出一支箭,总共需要4支箭。
#
# 示例 3:
# 输入:points = [[1,2],[2,3],[3,4],[4,5]]
# 输出:2
# 解释:气球可以用2支箭来爆破:
# - 在x = 2处发射箭,击破气球[1,2]和[2,3]。
# - 在x = 4处射出箭,击破气球[3,4]和[4,5]。
class Solution:
def findMinArrowShots(self, points):
if len(points) == 0:
return 0
points.sort()
res = 1
for i in range(1,len(points)):
if points[i][0] > points[i-1][1]: # 气球i和气球i-1不挨着,这里不是>=
res += 1
else:
points[i][1] = min(points[i-1][1],points[i][1]) # 每次遍历都缩小元素的右边界,如果下一个气球不挨着这个右边界,则另起一箭
return res
if __name__ == '__main__':
points = [[10, 16], [2, 8], [1, 6], [7, 12]]
# points = [[1, 2], [3, 4], [5, 6], [7, 8]]
# points = [[1, 2], [2, 3], [3, 4], [4, 5]]
points = [[9,12],[1,10],[4,11],[8,12],[3,9],[6,9],[6,7]]
tmp = Solution()
res = tmp.findMinArrowShots(points)
print(res)