目录
例1:LeetCode455. 分发饼干(easy)
例2:LeetCode376. 摆动序列(medium)
例3:LeetCode402. 移掉K位数字(medium)
例4:LeetCode55. 跳跃游戏(medium)
例5:LeetCode55. 跳跃游戏2(hard)
例6:LeetCode452. 用最少数量的箭引爆气球(medium)
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
注意:你可以假设胃口值为正。一个小朋友最多只能拥有一块饼干。
示例 1:
输入: [1,2,3], [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。示例 2:
输入: [1,2], [1,2,3]
输出: 2
解释:
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.
贪心想法:
算法设计:
代码:
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g.sort()
s.sort()
child = 0
cookie = 0
while child < len(g) and cookie < len(s):
if g[child] <= s[cookie]:
child += 1
cookie += 1
return child
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
示例 1:
输入: [1,7,4,9,2,5]
输出: 6
解释: 整个序列均为摆动序列。
示例 2:输入: [1,17,5,10,13,15,10,5,16,8]
输出: 7
解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。
贪心规律:
算法设计:
代码:
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
if len(nums) < 2:
return len(nums)
begin = 0
up = 1
down = 2
state = begin
max_length = 1
for i in range(1, len(nums)):
if state == begin:
if nums[i-1] < nums[i]:
state = up
max_length += 1
elif nums[i-1] > nums[i]:
state = down
max_length += 1
if state == up:
if nums[i-1] > nums[i]:
state = down
max_length += 1
if state == down:
if nums[i-1] < nums[i]:
state = up
max_length += 1
return max_length
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
注意:
num 的长度小于 10002 且 ≥ k。
num 不会包含任何前导零。
示例 1 :输入: num = "1432219", k = 3
输出: "1219"
解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。
示例 2 :输入: num = "10200", k = 1
输出: "200"
解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
贪心规律:
算法设计:
代码:
class Solution:
def removeKdigits(self, num: str, k: int) -> str:
s = []
result = ''
for i in range(len(num)):
number = int(num[i])
while len(s) != 0 and s[-1]>number and k>0:
s.pop()
k -= 1
if number != 0 or len(s) != 0:
s.append(number)
while len(s) != 0 and k>0:
s.pop()
k -= 1
result = result.join('%s'%q for q in s)
if result == '':
result = '0'
return result
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。
示例 2:输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
贪心算法:从前往后跳
class Solution:
def canJump(self, nums: List[int]) -> bool:
start = 0
end = 0
n = len(nums)
while start <= end and end < n-1:
end = max(end, start+nums[start])
start += 1
return end >= n-1
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
贪心规律:
算法设计:
代码:
class Solution:
def jump(self, nums: List[int]) -> int:
if len(nums) < 2: return 0
current_max_index = nums[0] # 当前可达到的最远位置
pre_max_max_index = nums[0] # 遍历当前位置到当前可达到的最远位置之间,可以达到的最远位置
jump_min = 1
for i in range(len(nums)):
if i > current_max_index: # 无法向前移动了在跳跃
jump_min += 1
current_max_index = pre_max_max_index
if pre_max_max_index < nums[i]+i:
pre_max_max_index = nums[i]+i
return jump_min
在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以y坐标并不重要,因此只要知道开始和结束的x坐标就足够了。开始坐标总是小于结束坐标。平面内最多存在104个气球。
一支弓箭可以沿着x轴从不同点完全垂直地射出。在坐标x处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被引爆。可以射出的弓箭的数量没有限制。 弓箭一旦被射出之后,可以无限地前进。我们想找到使得所有气球全部被引爆,所需的弓箭的最小数量。
Example:
输入:
[[10,16], [2,8], [1,6], [7,12]]输出:
2解释:
对于该样例,我们可以在x = 6(射爆[2,8],[1,6]两个气球)和 x = 11(射爆另外两个气球)。
算法思路:
代码:
class Solution:
def findMinArrowShots(self, points: List[List[int]]) -> int:
if len(points) == 0: return 0
points = sorted(points, key=lambda x: x[0])
shoot_num = 1 # 弓箭
shoot_begin = points[0][0]
shoot_end = points[0][1]
for i in range(len(points)):
if points[i][0] <= shoot_end:
shoot_begin = points[i][0]
if shoot_end > points[i][1]:
shoot_end = points[i][1]
else:
shoot_num += 1
shoot_begin = points[i][0]
shoot_end = points[i][1]
return shoot_num