Maximum Subsequence Score:排序 + 最小堆解决 nums1/nums2 双数组选 k 元素的最优解(LeetCode 2542)

发布时间:2026/9/18 6:06:23

Maximum Subsequence Score:排序 + 最小堆解决 nums1/nums2 双数组选 k 元素的最优解(LeetCode 2542) Maximum Subsequence Score排序 最小堆解决 nums1/nums2 双数组选 k 元素的最优解LeetCode 2542【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode本篇技术指南以 NeetCode 仓库中的 maximum-subsequence-score.md 为核心骨架完整讲解 LeetCode 2542「Maximum Subsequence Score」的三种解法从 $O(2^n)$ 的暴力递归到 $O(n\log n)$ 的按 nums2 降序排序 最小堆维护 nums1 前 k 大再到用位打包节省空间的 Min-Heap II 优化版。读者读完将掌握固定瓶颈元素 贪心维护 top-k这一经典双数组问题套路并可在本仓库 cpp、javascript、kotlin 等源码中对照验证实现细节。问题回顾给定两个长度均为n的下标平行数组nums1与nums2以及一个整数k。需要恰好选择k个下标i₁, i₂, …, iₖ使得分最大化$$ \text{score} \left(\sum_{j1}^{k} \text{nums1}[i_j]\right) \times \min_{j1}^{k} \left(\text{nums2}[i_j]\right) $$也就是说得分等于被选中的nums1元素之和乘以被选中的nums2元素中的最小值。由于n最大可达 $10^5$、元素值最大可达 $10^5$最终得分可能超过 32 位整数范围因此所有语言的实现如 cpp/2542-maximum-subsequence-score.cpp 中的long long、kotlin/2542-maximum-subsequence-score.kt 中的Long都使用 64 位整数作为返回值类型。前置知识Prerequisites原文档明确列出了攻克本题需要具备的四个基础能力堆 / 优先队列Heap / Priority Queue用最小堆高效维护nums1中已见过的k个最大值排序Sorting将配对(nums1[i], nums2[i])按nums2降序排列从而按当前最小候选值递减的顺序处理元素贪心算法Greedy Algorithms理解何时纳入、何时剔除元素才能最大化得分双数组协同Two Arrays Coordination处理下标必须同步的平行数组。1. 暴力解法递归枚举Brute Force, $O(2^n)$直觉Intuition题目要求恰好选择k个下标得分 所选nums1之和 × 所选nums2的最小值。由于选择是组合问题可以用递归尝试所有组合对每个下标要么选、要么不选。选择时更新累加和并同步追踪nums2中的最小值。算法步骤Algorithm定义递归函数参数为当前下标i、剩余需要选择的个数k、当前nums2最小值minVal、当前nums1累加和curSum基准情形当k 0时返回curSum * minVal若剩余元素不足i n或n - i k返回负无穷表示该分支非法若minVal 0直接返回0任何选择得分均为 0无需继续搜索枚举两个分支跳过当前下标选入当前下标更新minVal与curSum返回两个分支结果的较大者。各语言实现Pythonclass Solution: def maxScore(self, nums1: List[int], nums2: List[int], k: int) - int: n len(nums1) def dfs(i, k, minVal, curSum): if k 0: return curSum * minVal if i n or (n - i) k: return float(-inf) if minVal 0: return 0 res dfs(i 1, k, minVal, curSum) res max(res, dfs(i 1, k - 1, min(minVal, nums2[i]), curSum nums1[i])) return res return dfs(0, k, float(inf), 0)Javapublic class Solution { private int[] nums1, nums2; private int n; public long maxScore(int[] nums1, int[] nums2, int k) { this.nums1 nums1; this.nums2 nums2; this.n nums1.length; return dfs(0, k, Integer.MAX_VALUE, 0); } private long dfs(int i, int k, int minVal, long curSum) { if (k 0) { return curSum * minVal; } if (i n || (n - i) k) { return Integer.MIN_VALUE; } if (minVal 0) { return 0; } long res dfs(i 1, k, minVal, curSum); res Math.max( res, dfs(i 1, k - 1, Math.min(minVal, nums2[i]), curSum nums1[i]) ); return res; } }Cclass Solution { private: vectorint nums1, nums2; int n; public: long long maxScore(vectorint nums1, vectorint nums2, int k) { this-nums1 nums1; this-nums2 nums2; this-n nums1.size(); return dfs(0, k, INT_MAX, 0); } private: long long dfs(int i, int k, int minVal, long long curSum) { if (k 0) { return curSum * minVal; } if (i n || (n - i) k) { return INT_MIN; } if (minVal 0) { return 0; } long long res dfs(i 1, k, minVal, curSum); res max(res, dfs(i 1, k - 1, min(minVal, nums2[i]), curSum nums1[i])); return res; } };JavaScriptclass Solution { /** * param {number[]} nums1 * param {number[]} nums2 * param {number} k * return {number} */ maxScore(nums1, nums2, k) { const n nums1.length; const dfs (i, k, minVal, curSum) { if (k 0) { return curSum * minVal; } if (i n || n - i k) { return -Infinity; } if (minVal 0) { return 0; } let res dfs(i 1, k, minVal, curSum); res Math.max( res, dfs( i 1, k - 1, Math.min(minVal, nums2[i]), curSum nums1[i], ), ); return res; }; return dfs(0, k, Infinity, 0); } }Gofunc maxScore(nums1 []int, nums2 []int, k int) int64 { n : len(nums1) var dfs func(i, k, minVal int, curSum int64) int64 dfs func(i, k, minVal int, curSum int64) int64 { if k 0 { return curSum * int64(minVal) } if i n || n-i k { return math.MinInt64 } if minVal 0 { return 0 } res : dfs(i1, k, minVal, curSum) newMin : minVal if nums2[i] newMin { newMin nums2[i] } take : dfs(i1, k-1, newMin, curSumint64(nums1[i])) if take res { res take } return res } return dfs(0, k, math.MaxInt32, 0) }Kotlinclass Solution { private lateinit var nums1: IntArray private lateinit var nums2: IntArray private var n 0 fun maxScore(nums1: IntArray, nums2: IntArray, k: Int): Long { this.nums1 nums1 this.nums2 nums2 this.n nums1.size return dfs(0, k, Int.MAX_VALUE, 0L) } private fun dfs(i: Int, k: Int, minVal: Int, curSum: Long): Long { if (k 0) { return curSum * minVal } if (i n || n - i k) { return Long.MIN_VALUE } if (minVal 0) { return 0L } var res dfs(i 1, k, minVal, curSum) res maxOf(res, dfs(i 1, k - 1, minOf(minVal, nums2[i]), curSum nums1[i])) return res } }Swiftclass Solution { private var nums1 [Int]() private var nums2 [Int]() private var n 0 func maxScore(_ nums1: [Int], _ nums2: [Int], _ k: Int) - Int { self.nums1 nums1 self.nums2 nums2 self.n nums1.count return dfs(0, k, Int.max, 0) } private func dfs(_ i: Int, _ k: Int, _ minVal: Int, _ curSum: Int) - Int { if k 0 { return curSum * minVal } if i n || n - i k { return Int.min } if minVal 0 { return 0 } var res dfs(i 1, k, minVal, curSum) res max(res, dfs(i 1, k - 1, min(minVal, nums2[i]), curSum nums1[i])) return res } }Rustimpl Solution { pub fn max_score(nums1: Veci32, nums2: Veci32, k: i32) - i64 { let n nums1.len(); let k k as usize; fn dfs(i: usize, k: usize, min_val: i32, cur_sum: i64, nums1: [i32], nums2: [i32], n: usize) - i64 { if k 0 { return cur_sum * min_val as i64; } if i n || n - i k { return i64::MIN; } if min_val 0 { return 0; } let skip dfs(i 1, k, min_val, cur_sum, nums1, nums2, n); let take dfs(i 1, k - 1, min_val.min(nums2[i]), cur_sum nums1[i] as i64, nums1, nums2, n); skip.max(take) } dfs(0, k, i32::MAX, 0, nums1, nums2, n) } }复杂度时间复杂度$O(2^n)$ —— 每个下标都有选/不选两个分支空间复杂度$O(n)$ —— 递归栈深度。显然$O(2^n)$ 在 $n 10^5$ 的量级下完全不可行仅用于理解问题结构与验证小规模数据的正确性。2. 解法一排序 最小堆Min-Heap I, $O(n\log n)$直觉Intuition核心洞察如果固定了提供nums2最小值的那个元素那么在nums2值 ≥ 该最小值的所有元素中我们应该挑选nums1最大的k个。将配对按nums2降序排序并逐个处理时每遇到一个新元素它就自动成为当前窗口的新最小值因为它比前面所有元素都小或相等。此时只需用最小堆维护到目前为止见过的nums1中最大的k个值堆内元素之和即当前最优的nums1和与当前nums2值相乘即可得到以该元素为最小值的候选得分。算法步骤Algorithm构造(nums1[i], nums2[i])配对按nums2降序排序用最小堆维护已见过的nums1中最大的k个值维护堆内元素的运行和n1Sum按序遍历每个配对将nums1值入堆并更新n1Sum若堆大小超过k弹出堆顶最小值并从n1Sum中减去若堆大小恰为k计算得分n1Sum * 当前nums2并更新答案返回最大得分。各语言实现Pythonclass Solution: def maxScore(self, nums1: List[int], nums2: List[int], k: int) - int: pairs sorted(zip(nums1, nums2), keylambda p: p[1], reverseTrue) minHeap [] n1Sum 0 res 0 for n1, n2 in pairs: n1Sum n1 heapq.heappush(minHeap, n1) if len(minHeap) k: n1Sum - heapq.heappop(minHeap) if len(minHeap) k: res max(res, n1Sum * n2) return resJavapublic class Solution { public long maxScore(int[] nums1, int[] nums2, int k) { int n nums1.length; int[][] pairs new int[n][2]; for (int i 0; i n; i) { pairs[i][0] nums1[i]; pairs[i][1] nums2[i]; } Arrays.sort(pairs, (a, b) - Integer.compare(b[1], a[1])); PriorityQueueInteger minHeap new PriorityQueue(); long n1Sum 0, res 0; for (int[] pair : pairs) { n1Sum pair[0]; minHeap.offer(pair[0]); if (minHeap.size() k) { n1Sum - minHeap.poll(); } if (minHeap.size() k) { res Math.max(res, n1Sum * pair[1]); } } return res; } }Cclass Solution { public: long long maxScore(vectorint nums1, vectorint nums2, int k) { int n nums1.size(); vectorpairint, int pairs(n); for (int i 0; i n; i) { pairs[i] {nums1[i], nums2[i]}; } sort(pairs.begin(), pairs.end(), [](const auto a, const auto b) { return b.second a.second; }); priority_queueint, vectorint, greaterint minHeap; long long n1Sum 0, res 0; for (auto pair : pairs) { n1Sum pair.first; minHeap.push(pair.first); if (minHeap.size() k) { n1Sum - minHeap.top(); minHeap.pop(); } if (minHeap.size() k) { res max(res, n1Sum * (long long)pair.second); } } return res; } };JavaScriptclass Solution { /** * param {number[]} nums1 * param {number[]} nums2 * param {number} k * return {number} */ maxScore(nums1, nums2, k) { let pairs nums1.map((n1, i) [n1, nums2[i]]); pairs.sort((a, b) b[1] - a[1]); let minHeap new MinPriorityQueue(); let n1Sum 0, res 0; for (let [n1, n2] of pairs) { n1Sum n1; minHeap.enqueue(n1); if (minHeap.size() k) { n1Sum - minHeap.dequeue(); } if (minHeap.size() k) { res Math.max(res, n1Sum * n2); } } return res; } }Gofunc maxScore(nums1 []int, nums2 []int, k int) int64 { n : len(nums1) pairs : make([][2]int, n) for i : 0; i n; i { pairs[i] [2]int{nums1[i], nums2[i]} } sort.Slice(pairs, func(i, j int) bool { return pairs[i][1] pairs[j][1] }) minHeap : IntHeap{} heap.Init(minHeap) var n1Sum int64 0 var res int64 0 for _, pair : range pairs { n1Sum int64(pair[0]) heap.Push(minHeap, pair[0]) if minHeap.Len() k { n1Sum - int64(heap.Pop(minHeap).(int)) } if minHeap.Len() k { cur : n1Sum * int64(pair[1]) if cur res { res cur } } } return res } type IntHeap []int func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Less(i, j int) bool { return h[i] h[j] } func (h IntHeap) Swap(i, j int) { h[i], h[j] h[j], h[i] } func (h *IntHeap) Push(x any) { *h append(*h, x.(int)) } func (h *IntHeap) Pop() any { old : *h n : len(old) x : old[n-1] *h old[0 : n-1] return x }Kotlinclass Solution { fun maxScore(nums1: IntArray, nums2: IntArray, k: Int): Long { val n nums1.size val pairs Array(n) { intArrayOf(nums1[it], nums2[it]) } pairs.sortByDescending { it[1] } val minHeap PriorityQueueInt() var n1Sum 0L var res 0L for (pair in pairs) { n1Sum pair[0] minHeap.offer(pair[0]) if (minHeap.size k) { n1Sum - minHeap.poll() } if (minHeap.size k) { res maxOf(res, n1Sum * pair[1]) } } return res } }Swiftclass Solution { func maxScore(_ nums1: [Int], _ nums2: [Int], _ k: Int) - Int { let n nums1.count var pairs (0..n).map { (nums1[$0], nums2[$0]) } pairs.sort { $0.1 $1.1 } var minHeap HeapInt() var n1Sum 0 var res 0 for (n1, n2) in pairs { n1Sum n1 minHeap.insert(n1) if minHeap.count k { n1Sum - minHeap.removeMin() } if minHeap.count k { res max(res, n1Sum * n2) } } return res } }Rustimpl Solution { pub fn max_score(nums1: Veci32, nums2: Veci32, k: i32) - i64 { let n nums1.len(); let k k as usize; let mut pairs: Vec(i32, i32) nums1.iter().zip(nums2.iter()) .map(|(a, b)| (a, b)).collect(); pairs.sort_by(|a, b| b.1.cmp(a.1)); let mut min_heap BinaryHeap::new(); let mut n1_sum: i64 0; let mut res: i64 0; for (n1, n2) in pairs { n1_sum n1 as i64; min_heap.push(std::cmp::Reverse(n1 as i64)); if min_heap.len() k { if let Some(std::cmp::Reverse(val)) min_heap.pop() { n1_sum - val; } } if min_heap.len() k { res res.max(n1_sum * n2 as i64); } } res } }仓库源码对照本仓库中该题的 C 实现 与上述算法完全一致sort使用 lambda 按pairs[i].second即nums2降序排列随后priority_queueint, vectorint, greaterint作为最小堆维护前k大弹出堆顶时同步从currSum中扣除JavaScript 实现 使用MinPriorityQueue并在注释中标注了复杂度Time O(n*log(n)) | space O(n)Kotlin 实现 则用zipsortedWith(compareBy({ -it.second }))完成配对与降序排序。三份源码均为解法一的标准落地可作为交叉验证。走查示例以nums1 [1, 3, 3, 2]、nums2 [2, 1, 3, 4]、k 3为例配对并按nums2降序(2,4), (3,3), (1,2), (3,1)处理(2,4)堆[2]sum2不足k不计算处理(3,3)堆[2,3]sum5不足k处理(1,2)堆[1,2,3]sum6大小恰为k→ 候选6×212处理(3,1)堆[1,2,3,3]sum9超k→ 弹出1sum8堆[2,3,3]大小恰为k→ 候选8×18最大得分为12。复杂度时间复杂度$O(n\log n)$ —— 排序 $O(n\log n)$每个元素入堆/出堆各 $O(\log k) \le O(\log n)$空间复杂度$O(n)$ —— 配对数组与堆。3. 解法二位打包优化Min-Heap II直觉Intuition这是解法一的空间优化变体把两个值打包进一个 64 位整数。由于题目约束元素值最大为 $10^5$小于 $2^{30}$可以用移位把nums2放高位、nums1放低位combined (nums2[i] 30) | nums1[i]。对打包值排序即等价于按nums2排序遍历时再用位运算把两个原始值解包出来。这样省去了存放(n1, n2)配对结构pair/tuple的开销只用一维数组即可完成排序与遍历。算法步骤Algorithm对每个下标构造打包值(nums2[i] 30) | nums1[i]将打包数组降序排序等价于按nums2主序降序依次处理每个打包值用位运算解包n1 num ((1 30) - 1)n2 num 30将n1入堆并累加n1Sum堆超k则弹出最小值并扣除堆大小恰为k时计算n1Sum * n2并追踪最大值返回最大得分。说明 30需要 64 位整数承载Java/C/Go/Kotlin 使用long/int64/LongJavaScript 使用BigInt且要求nums1[i] 2^30本题约束 $10^5$ 满足该前提。各语言实现Pythonclass Solution: def maxScore(self, nums1: List[int], nums2: List[int], k: int) - int: n len(nums1) arr [(nums2[i] 30) | nums1[i] for i in range(n)] arr.sort(reverseTrue) minHeap [] n1Sum 0 res 0 for num in arr: n1, n2 num ((1 30) - 1), num 30 n1Sum n1 heapq.heappush(minHeap, n1) if len(minHeap) k: n1Sum - heapq.heappop(minHeap) if len(minHeap) k: res max(res, n1Sum * n2) return resJavapublic class Solution { public long maxScore(int[] nums1, int[] nums2, int k) { int n nums1.length; long[] arr new long[n]; for (int i 0; i n; i) { arr[i] ((long) nums2[i] 30) | nums1[i]; } Arrays.sort(arr); PriorityQueueInteger minHeap new PriorityQueue(); long n1Sum 0, res 0; for (int i n - 1; i 0; i--) { int n1 (int) (arr[i] ((1L 30) - 1)); int n2 (int) (arr[i] 30); n1Sum n1; minHeap.offer(n1); if (minHeap.size() k) { n1Sum - minHeap.poll(); } if (minHeap.size() k) { res Math.max(res, n1Sum * (long) n2); } } return res; } }Cclass Solution { public: long long maxScore(vectorint nums1, vectorint nums2, int k) { int n nums1.size(); vectorlong long arr(n); for (int i 0; i n; i) { arr[i] ((long long) nums2[i] 30) | nums1[i]; } sort(arr.rbegin(), arr.rend()); priority_queueint, vectorint, greaterint minHeap; long long n1Sum 0, res 0; for (long long num : arr) { int n1 num ((1LL 30) - 1); int n2 num 30; n1Sum n1; minHeap.push(n1); if (minHeap.size() k) { n1Sum - minHeap.top(); minHeap.pop(); } if (minHeap.size() k) { res max(res, n1Sum * (long long)n2); } } return res; } };JavaScriptclass Solution { /** * param {number[]} nums1 * param {number[]} nums2 * param {number} k * return {number} */ maxScore(nums1, nums2, k) { const n nums1.length; const arr []; for (let i 0; i n; i) { arr.push((BigInt(nums2[i]) BigInt(30)) | BigInt(nums1[i])); } arr.sort((a, b) Number(b - a)); const minHeap new MinPriorityQueue(); let n1Sum 0n, res 0n; for (let num of arr) { let n1 Number(num ((1n 30n) - 1n)); let n2 Number(num 30n); n1Sum BigInt(n1); minHeap.enqueue(n1); if (minHeap.size() k) { n1Sum - BigInt(minHeap.dequeue()); } if (minHeap.size() k) { res BigInt(Math.max(Number(res), Number(n1Sum * BigInt(n2)))); } } return Number(res); } }Gofunc maxScore(nums1 []int, nums2 []int, k int) int64 { n : len(nums1) arr : make([]int64, n) for i : 0; i n; i { arr[i] (int64(nums2[i]) 30) | int64(nums1[i]) } sort.Slice(arr, func(i, j int) bool { return arr[i] arr[j] }) minHeap : IntHeap{} heap.Init(minHeap) var n1Sum int64 0 var res int64 0 for _, num : range arr { n1 : int(num ((1 30) - 1)) n2 : int(num 30) n1Sum int64(n1) heap.Push(minHeap, n1) if minHeap.Len() k { n1Sum - int64(heap.Pop(minHeap).(int)) } if minHeap.Len() k { cur : n1Sum * int64(n2) if cur res { res cur } } } return res } type IntHeap []int func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Less(i, j int) bool { return h[i] h[j] } func (h IntHeap) Swap(i, j int) { h[i], h[j] h[j], h[i] } func (h *IntHeap) Push(x any) { *h append(*h, x.(int)) } func (h *IntHeap) Pop() any { old : *h n : len(old) x : old[n-1] *h old[0 : n-1] return x }Kotlinclass Solution { fun maxScore(nums1: IntArray, nums2: IntArray, k: Int): Long { val n nums1.size val arr LongArray(n) { (nums2[it].toLong() shl 30) or nums1[it].toLong() } arr.sortDescending() val minHeap PriorityQueueInt() var n1Sum 0L var res 0L for (num in arr) { val n1 (num and ((1L shl 30) - 1)).toInt() val n2 (num shr 30).toInt() n1Sum n1 minHeap.offer(n1) if (minHeap.size k) { n1Sum - minHeap.poll() } if (minHeap.size k) { res maxOf(res, n1Sum * n2) } } return res } }Swiftclass Solution { func maxScore(_ nums1: [Int], _ nums2: [Int], _ k: Int) - Int { let n nums1.count var arr (0..n).map { (Int64(nums2[$0]) 30) | Int64(nums1[$0]) } arr.sort { $0 $1 } var minHeap HeapInt() var n1Sum: Int64 0 var res: Int64 0 for num in arr { let n1 Int(num ((1 30) - 1)) let n2 Int(num 30) n1Sum Int64(n1) minHeap.insert(n1) if minHeap.count k { n1Sum - Int64(minHeap.removeMin()) } if minHeap.count k { let cur n1Sum * Int64(n2) if cur res { res cur } } } return Int(res) } }Rustimpl Solution { pub fn max_score(nums1: Veci32, nums2: Veci32, k: i32) - i64 { let n nums1.len(); let k k as usize; let mut arr: Veci64 (0..n) .map(|i| ((nums2[i] as i64) 30) | (nums1[i] as i64)) .collect(); arr.sort_unstable_by(|a, b| b.cmp(a)); let mut min_heap BinaryHeap::new(); let mut n1_sum: i64 0; let mut res: i64 0; for num in arr { let n1 (num ((1 30) - 1)) as i64; let n2 (num 30) as i64; n1_sum n1; min_heap.push(std::cmp::Reverse(n1)); if min_heap.len() k { if let Some(std::cmp::Reverse(val)) min_heap.pop() { n1_sum - val; } } if min_heap.len() k { res res.max(n1_sum * n2); } } res } }复杂度时间复杂度$O(n\log n)$ —— 与解法一相同排序占主导空间复杂度$O(n)$ —— 但只使用一个一维long/BigInt数组省去显式的配对结构。4. 常见陷阱Common Pitfalls4.1 误用最大堆而非最小堆目标是最大化nums1中k个元素的和必须保留已见过的k个最大值。这要求使用最小堆当堆超过k个元素时堆顶就是当前最小的元素可以 $O(\log k)$ 弹出。若误用最大堆弹出的将是最大值无法高效剔除最小元素导致无法正确维护前 k 大结果错误。4.2 忘记按 nums2 降序排序算法正确性的前提是按nums2递减处理使得每遇到一个新元素它就自动成为新的最小值。如果升序排序或干脆不排序新元素即新最小值的不变量被破坏最小值追踪失效得分计算错误。4.3 弹出堆顶后忘记同步更新运行和当堆大小超过k弹出最小元素时必须同时从运行和中减去该元素的值。若漏掉这一步n1Sum会包含已不在堆中的元素导致得分被高估、结果错误。4.4 溢出风险最终得分最大约为 $k \times 10^5 \times 10^5$当 $k$ 接近 $10^5$ 时会超过 32 位整数范围因此所有实现均使用 64 位整数Python 原生大整数无需处理其余语言统一用long long/Long/BigInt/i64。5. 总结解法核心思路时间复杂度空间复杂度暴力递归枚举所有组合追踪最小nums2与nums1和$O(2^n)$$O(n)$Min-Heap I按nums2降序排序 最小堆维护nums1前k大$O(n\log n)$$O(n)$Min-Heap II位打包(nums2 30) | nums1单数组排序 最小堆$O(n\log n)$$O(n)$本题的核心套路是**枚举瓶颈最小值 贪心维护其余维度前 k 大**先固定得分公式中的瓶颈项nums2的最小值再在约束下贪心最大化另一项nums1的和。这一思路在同仓库的 put-marbles-in-bags.md、best-team-with-no-conflicts.md、maximum-score-after-n-operations.md 等排序 堆类问题中反复出现面试中属于高频考察方向。仓库 README见 README.md 的解题状态表记录了该题在 C、JavaScript、Kotlin 三种语言下的完整实现可直接对照学习。【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/18 6:01:23

PDF补丁丁:免费PDF工具箱30秒上手,修书签、合并拆分一次搞定

PDF补丁丁:免费PDF工具箱30秒上手,修书签、合并拆分一次搞定 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱,可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档,探查文档结构,提取图片、转成图片等等 项目…

2026/9/18 6:01:23

刚性配准与非刚性配准:从自由度到医学图像配准管线实战

做过配准这行的人应该都有同感:刚接触刚性配准和非刚性配准的时候,最容易懵的还不是算法公式,而是搞不清楚这两个东西到底分别该用在什么场景、为什么有时候明明配准成功了结果却是错的。尤其是医学图像处理里,同一个病人的CT和MR…

2026/9/18 7:01:26

Scratch光线投射实现伪3D教学实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 7:01:26

开放代码评审:把Code Review从形式变为团队技术基础设施

1. 先想清楚:open-code-review 到底在解决什么问题代码评审这事,几乎所有技术团队都在做,但真正做得好的少。大部分团队所谓的 code review,要么是走个过场在 PR 底下回个 LGTM,要么变成两个人坐在一起口述上下文&…

2026/9/18 7:01:26

AI课程论文写作助手:智能扩写与格式自动化解析

1. 项目背景与痛点解析每到期末季,高校学子们都会面临课程论文的集体焦虑。根据我在教育科技行业十年的观察,学生撰写课程论文时普遍存在三大核心痛点:内容生产压力:面对3000字起步的论文要求,70%的学生表示"凑字…

2026/9/18 7:01:26

开放式代码评审如何落地?从流程设计到工具配置的完整实践指南

在团队里待久了你会发现一个挺扎心的现象:code review 这个环节,大多数时候只有两种状态——要么是合代码前的过场,要么是合完代码后的甩锅现场。我前后带过十几个项目、也帮别的团队做过好几次评审流程优化,慢慢意识到问题往往不…

2026/9/18 6:56:25

如何用AI Dev Kit让AI写出指标视图:metric-views技能实战

如何用AI Dev Kit让AI写出指标视图:metric-views技能实战 【免费下载链接】ai-dev-kit Databricks Toolkit for Coding Agents provided by Field Engineering 项目地址: https://gitcode.com/GitHub_Trending/ai/ai-dev-kit AI Dev Kit 是 Databricks 开源的…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/18 0:01:09

Google Colab 实战:运行模型、数据加载与报错排查

1. 为什么我劝你先搞懂 Colab 的运行模型1.1 Colab 到底是什么,跟本地跑代码差在哪Google Colab 简单说就是一台跑在浏览器里的 Linux 虚拟机,你打开一个 Notebook,背后就连上了一台带 GPU 的远程机器。你在单元格里敲的每一行 Python&#x…

2026/9/18 0:01:09

C语言数据类型与表达式详解

1. C语言数据与数据类型概述在C语言编程中,数据是程序处理的核心对象。理解数据的分类和特性是掌握C语言的基础。C语言中的数据主要分为四大类:常量、变量、表达式和函数。这些数据类型构成了C语言程序的基本元素,每种类型都有其独特的特性和…

2026/9/18 0:01:09

SQL时间字段指定时间段查询:区间语义、索引与时区避坑

上周排查一个线上问题&#xff0c;用户反馈"昨天的订单一条都没查到"&#xff0c;但数据库里明明躺着两千多条。最后定位下来&#xff0c;不是数据丢了&#xff0c;也不是接口挂了&#xff0c;而是那个查询条件把时间段写成了> 2024-05-20 00:00:00 AND < 2024…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码