验证选最多元素和≤K的排序算法,求无排序实现思路
算法问题解答:选最多元素使和≤k
一、排序后算法的正确性分析
你的贪心思路是完全成立的:要选中最多数量的元素,优先选最小的元素是最优策略——因为替换任何一个小元素为大元素,要么总和会超过k,要么无法增加元素数量。但你的代码存在边界场景的漏洞,比如:
- 当数组为空时,直接访问
L[0]会报错; - 当第一个元素就大于k时(比如输入
findSumCount([6], 5)),代码会错误返回1,正确结果应为0。
修正后的排序版代码可以覆盖所有场景:
def findSumCount(L, k): if not L: return 0 L.sort() total_sum = 0 count = 0 for num in L: if total_sum + num <= k: total_sum += num count += 1 else: break # 数组已排序,后续元素更大,无需继续遍历 return count
二、不预先排序的实现思路
如果不提前排序,核心还是要尽可能保留更多小元素,推荐用最大堆动态维护选中元素集合,具体逻辑如下:
- 用堆记录当前选中的元素(Python默认最小堆,可存负值模拟最大堆);
- 遍历每个元素时先加入堆并累加总和;
- 若总和超过k,移除堆中最大的元素(它对总和的贡献最大,移除后能最大程度腾出空间),同时减去对应值;
- 遍历结束后,堆的大小就是最多可选中的元素数量。
Python实现示例:
import heapq def findSumCount_no_sort(L, k): max_heap = [] total_sum = 0 count = 0 for num in L: heapq.heappush(max_heap, -num) # 存负值模拟最大堆 total_sum += num count += 1 # 总和超限时,持续移除最大元素直到总和符合要求 while total_sum > k and max_heap: removed = -heapq.heappop(max_heap) total_sum -= removed count -= 1 return count
这种方法的时间复杂度为O(n log m)(m为最终选中元素的数量),当m远小于n时,效率会优于排序的O(n log n)。
内容的提问来源于stack exchange,提问作者Catarina Nogueira
相关产品推荐
相关产品推荐

