给定整数数组 nums
和整数 k
,请返回数组中第 **k**
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
你必须设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
1 2 输入: [3,2,1,5,6,4], k = 2 输出: 5
示例 2:
1 2 输入: [3,2,3,1 ,2,4,5,5 ,6 ], k = 4 输出: 4
提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
思路 毫无思路可言,sorted直接搞定
代码 1 2 3 class Solution : def findKthLargest (self, nums: List [int ], k: int ) -> int : return sorted (nums, reverse=True )[k-1 ]
还有一个我之前写的版本,也顺便发一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution : def findKthLargest (self, nums: List [int ], k: int ) -> int : def quick_select (nums, k ): pivot = random.choice(nums) big, equal, small = [], [], [] for num in nums: if num > pivot: big.append(num) elif num < pivot: small.append(num) else : equal.append(num) if k <= len (big): return quick_select(big, k) if len (nums) - len (small) < k: return quick_select(small, k - len (nums) + len (small)) return pivot return quick_select(nums, k)
时间复杂度 时间复杂度O(n log n),空间复杂度O(n),执行时间128ms,消耗内存27.3MB
502 IPO Hard 假设 力扣(LeetCode)即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k
个不同的项目。帮助 力扣 设计完成最多 k
个不同项目后得到最大总资本的方式。
给你 n
个项目。对于每个项目 i
,它都有一个纯利润 profits[i]
,和启动该项目需要的最小资本 capital[i]
。
最初,你的资本为 w
。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。
总而言之,从给定项目中选择 最多 k
个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。
答案保证在 32 位有符号整数范围内。
示例 1:
1 2 3 4 5 6 7 8 输入:k = 2, w = 0, profits = [1,2,3], capital = [0,1,1] 输出:4 解释: 由于你的初始资本为 0,你仅可以从 0 号项目开始。 在完成后,你将获得 1 的利润,你的总资本将变为 1。 此时你可以选择开始 1 号或 2 号项目。 由于你最多可以选择两个项目,所以你需要完成 2 号项目以获得最大的资本。 因此,输出最后最大化的资本,为 0 + 1 + 3 = 4。
示例 2:
1 2 输入:k = 3, w = 0, profits = , capital = 输出:6
提示:
1 <= k <= 105
0 <= w <= 109
n == profits.length
n == capital.length
1 <= n <= 105
0 <= profits[i] <= 104
0 <= capital[i] <= 109
思路
排序后方便进行,可以直接考虑当前资金
用最大堆来维护利润,堆顶元素就是当前能够启动的里面利润最大的
选择项目,每次迭代后将能够启动的项目加入最大堆并选择最大利润的启动
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution : def findMaximizedCapital (self, k: int , W: int , Profits: List [int ], Capital: List [int ] ) -> int : n = len (Profits) projects = sorted (zip (Capital, Profits)) max_heap = [] idx = 0 for _ in range (k): while idx < n and projects[idx][0 ] <= W: heapq.heappush(max_heap, -projects[idx][1 ]) idx += 1 if max_heap: W -= heapq.heappop(max_heap) else : break return W
时间复杂度 时间复杂度O(n log n),空间复杂度O(n),执行时间380ms,消耗内存40.4MB
给定两个以 非递减顺序排列 的整数数组 nums1
和 nums2
, 以及一个整数 k
。
定义一对值 (u,v)
,其中第一个元素来自 nums1
,第二个元素来自 nums2
。
请找到和最小的 k
个数对 (u1,v1)
, (u2,v2)
… (uk,vk)
。
示例 1:
1 2 3 4 输入: nums1 = , nums2 = , k = 3 输出: ,, 解释: 返回序列中的前 3 对数: ,,,,,,,,
示例 2:
1 2 3 4 输入: nums1 = , nums2 = , k = 2 输出: , 解释: 返回序列中的前 2 对数: ,,,,,,,,
提示:
1 <= nums1.length, nums2.length <= 105
-109 <= nums1[i], nums2[i] <= 109
nums1
和 nums2
均为 升序排列
1 <= k <= 104
k <= nums1.length * nums2.length
思路 首先需要明确的是,我们是需要找到最小的一对数,而最小的评定是两个数的加和最小
然后我们需要将nums1里的每个元素与nums2的第一个元素进行配对并计算和,然后放入最小堆中
接下来利用循环找到最小的k个对并弹出堆顶元素(最小配对)并添加到ans
接下来我们需要检查nums2是否有其他元素,有的话往下移然后继续匹配
代码 1 2 3 4 5 6 7 8 9 10 class Solution : def kSmallestPairs (self, nums1: List [int ], nums2: List [int ], k: int ) -> List [List [int ]]: ans = [] h = [(nums1[i] + nums2[0 ], i, 0 ) for i in range (min (len (nums1), k))] while len (ans) < k: _, i, j = heappop(h) ans.append([nums1[i], nums2[j]]) if j + 1 < len (nums2): heappush(h, (nums1[i] + nums2[j + 1 ], i, j + 1 )) return ans
时间复杂度 时间复杂度O(k log k),空间复杂度O(k),执行时间139ms,消耗内存32.4MB