435. 无重叠区间(贪心)
贪心策略是:尽可能让选入的区间的右边界小,因为这样才能纳入更多的区间,相应的不需要删去太多区间。这就达到了减去最小区间数而使得区间不重叠。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1]) # 根据右边界排序
ans = [intervals[0]] #先纳入第一个区间 这样的写法稍微复杂一些。可以简略点
a = 0 # 用来遍历ans的下标
num = 0 # 记录删去的数目
for i in intervals[1:]: # 从第二个开始遍历
if i[0] < ans[a][1]: # 如果该区间左边界小于上一个选定区间的右边界,就进行“删除”,删除数一
num += 1
else:
ans.append(i) # 满足条件就纳入
a += 1 # 准备下一次使用
return num
605. 种花问题(贪心)
代码写得很丑,思路比较简单。
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
lenth = len(flowerbed) # 计算种花区间
num = 0 # 最终的答案
for i in range(lenth):
if flowerbed[i] == 0: # 如果当前有位置
# 第一种情况:并且当前位置处于开头,在空间足够大的情况下,判断相邻是否有花
if i == 0 and lenth >= 2 and flowerbed[i+1] == 0:
flowerbed[i] = 1 # 可以种花就种
num += 1 # 数量加一
if i >= 1 and i < lenth - 1: # 第二种情况,在中间位置
if flowerbed[i-1] == 0 and flowerbed[i+1] == 0: # 左右无花
flowerbed[i] = 1 # 种!
num += 1
if i == lenth - 1 and flowerbed[i-1] == 0: # 最后位置,相邻的左边无花
flowerbed[i] = 1 # 种!
num += 1
return num >= n # 返回bool
题解思路:
一个公式:能种花位置数 P 与最多花的数量M关系是: (P + 1)/ 2
-
在 下标i 和 j 种了花,且
[i+1, j-1]
之间没有花。 -
那么只有当
j-i>=4
时才可以在下标 i 和 j 之间种花 -
可种花下标
[i+2, j-2]
-
能种花的位置数是
p = j-i-3
(理解为-1-2 1是左边i的那个位置,2是左右都要空一个位置才能种) -
p为奇数 最多可种
(p+1)/2
-
p为偶数 最多可种
p/2
因为整数除法规则 两者相等 -
所以 能种
(j-i-2)/2
朵 -
如果 l 的左边没有种花,r 的右边没有种花,记为空格下标 k
-
flowerbed[ k ] = 0
-
(将下标 l 理解为下标 l 处左边还有多少个空地)如果 l < 2无法在左边种花(只有两个位置,必定相邻) ; l >= 2 可在(下标 l-2理解为当前的左边第二个为界限)[0, l-2] 范围种花,可以种植 l - 1(左边有l个位置,需要隔出一个),最多l / 2 朵花
-
令 m为数组flowerbed 长度下标r右边有
m-r-1
个位置,可种m-r-2
, 最多可种(m-r-1)/2
朵花 -
如果没有任何花 ,可种 (m+1)/2 朵
根据上述计算方法,计算最多可种的数量,加以判断>=n
class Solution:
def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
count, m, prev = 0, len(flowerbed), -1
for i in range(m):
if flowerbed[i] == 1:
if prev < 0: # 一开始第一次遇到花
count += i // 2 # 计算(i-1)为前段可种的位置数,(位置数+1)/2
else: # 之后遇到了花
# prev是上回花的位置, i是前面的位置
count += (i - prev - 2) // 2 # 理解:(位置数+1)/2 (i-prev-3+1)
prev = i
if prev < 0: # 一直没遇到花 计算全盘能种多少花
count += (m + 1) // 2 # 理解:(位置数+1)/2
else: # 遍历完之后再来一次 这种情况是最后一个没有花
count += (m - prev - 1) // 2 # 理解:(位置数+1)/2 (m-prev-2+1)
return count >= n
理解了半天终于懂了咳咳。