作为一名经历过多次算法面试的老兵,我深知贪心算法在实际面试中的高频出现率。今天我们就来拆解三个经典贪心算法问题:分发饼干、摆动序列和最大子序和。这些题目看似简单,但其中蕴含的解题思路和优化技巧,正是大厂面试官最看重的核心能力。
这个问题本质上是一个典型的"资源最优分配"问题。我们需要将有限的饼干(资源)分配给胃口值不同的孩子,目标是让尽可能多的孩子得到满足。
关键洞察点在于:
最优解法需要先对两个数组排序:
python复制def findContentChildren(g, s):
g.sort()
s.sort()
child = cookie = 0
while child < len(g) and cookie < len(s):
if s[cookie] >= g[child]:
child += 1
cookie += 1
return child
关键操作解析:
重要提示:这个解法之所以有效,是因为我们总尝试用最小的饼干满足最小的需求,这样可以保留更大的饼干满足更难满足的孩子。
摆动序列要求连续数字之间的差值正负交替。这个问题考察的是对序列趋势的把握能力。
实际应用场景包括:
我们可以通过统计峰值数量来解决问题:
python复制def wiggleMaxLength(nums):
if len(nums) < 2:
return len(nums)
prev_diff = nums[1] - nums[0]
count = 2 if prev_diff != 0 else 1
for i in range(2, len(nums)):
curr_diff = nums[i] - nums[i-1]
if (curr_diff > 0 and prev_diff <= 0) or (curr_diff < 0 and prev_diff >= 0):
count += 1
prev_diff = curr_diff
return count
算法核心思想:
给定整数数组nums,找出具有最大和的连续子数组。这个问题有多个变种:
最优解法是Kadane算法,时间复杂度O(n):
python复制def maxSubArray(nums):
max_current = max_global = nums[0]
for num in nums[1:]:
max_current = max(num, max_current + num)
max_global = max(max_global, max_current)
return max_global
算法核心思想:
为什么这个贪心策略有效?
贪心算法适用于问题具有以下特性:
除了贪心法,还可以:
如果需要返回子数组本身:
python复制def maxSubArrayWithIndices(nums):
max_current = max_global = nums[0]
start = end = 0
current_start = 0
for i in range(1, len(nums)):
if nums[i] > max_current + nums[i]:
max_current = nums[i]
current_start = i
else:
max_current += nums[i]
if max_current > max_global:
max_global = max_current
start = current_start
end = i
return (max_global, start, end)
贪心算法的精妙之处在于它用局部的眼光做出全局最优的选择。这三个题目虽然表面不同,但都体现了贪心算法的核心思想:在每一步选择中采取当前状态下最优的选择,从而希望导致全局最优的结果。