860.柠檬水找零
- LeetCode
思路: 这个问题比较简单, 用一个字典bill_dict记录已经收到的钱已经钱的数量, 然后如果收到五元, 字典中的 bill_dict[5] += 1。 收到10元 bill_dict[5] -= 1 bill_dict[10] += 1 。 麻烦的是收到20元, 这时候我们应该优先找 一个10元和一个5元, 没有10元的时候, 找三个五元。 然后叠加判断没办法找零的条件就可以了。
难点: 无
class Solution:def lemonadeChange(self, bills: List[int]) -> bool:collected_bills = defaultdict(int)for bill in bills:if bill == 5:collected_bills[5] += 1elif bill == 10: # give out 5 billscollected_bills[10] += 1collected_bills[5] -= 1if collected_bills[5] < 0:return Falseelse: # give out 15 billsif collected_bills[5] > 0 and collected_bills[10] > 0:collected_bills[20] += 1collected_bills[5] -= 1collected_bills[10] -= 1elif collected_bills[5] > 2:collected_bills[5] -= 3else:return Falsereturn True
406.根据身高重建队列
- LeetCode
思路: 这个问题有点难卡了,我好几天。。。 一开始的思路是先对 k 排序, 然后对 h 排序, 那么k=0 的时候等于已经排好了,然后对 k=1 的时候, 往前找到一个比它的h大一个的数字insert进去就行了。 但是这样代码运行的很慢。 然后发现其实先对 h 倒序排列然后在对k顺序排列要简单很多, 因为当loop 一个 h 的时候可以保证前面的h都是大于这个元素的 h的。
难点: 排序的方式比较难想到。
class Solution:def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:people.sort(key=lambda x: [-x[0], x[1]])i, n = 0, len(people)while i < n:k = people[i][1]if k >= i:i += 1continueelse:tmp = people.pop(i)people.insert(k, tmp)i += 1return people
452. 用最少数量的箭引爆气球
思路: 这个题是求重叠的区间的问题的。 首先对数组排序,如果发现下一个point 的end 大于前一个point 的start, 就丢掉这两个point 转而insert 一个新的point, 这个新的point 表示两者的重叠区间。 最后看看还剩几个point 就可以了。
难点: 第一次提交失败了,因为重叠区间的定义出了逻辑bug, 重叠区间的 end 应该是两个区间end的最小值。
class Solution:def findMinArrowShots(self, points: List[List[int]]) -> int:points.sort()points = points[1:] + [points[0]]i, n = 0, len(points)while i < n-1:point = points.pop(0)if point[0] <= points[-1][1]:last_point = points.pop()points.append([max(point[0], last_point[0]), min(point[1], last_point[1])])else:points.append(point)i += 1return len(points)