LeetCode算法日記 - Day 25: 數組中的第K個最大元素、庫存管理III

目錄

1 數組中的第K個最大元素

1.1 題目解析

1.2 解法

1.3 代碼實現

2. 庫存管理III

2.1 題目解析

2.2 解法

2.3 代碼實現


1 數組中的第K個最大元素

215. 數組中的第K個最大元素 - 力扣(LeetCode)

給定整數數組?nums?和整數?k,請返回數組中第?k?個最大的元素。

請注意,你需要找的是數組排序后的第?k?個最大的元素,而不是第?k?個不同的元素。

你必須設計并實現時間復雜度為?O(n)?的算法解決此問題。

示例 1:

輸入: [3,2,1,5,6,4], k = 2
輸出: 5

示例?2:

輸入: [3,2,3,1,2,4,5,5,6], k = 4
輸出: 4

提示:

  • 1 <= k <= nums.length <= 105
  • -104?<= nums[i] <= 104

1.1 題目解析

題目本質

這是一個 選擇問題:在一堆數里,不用全排好順序,只要找到 第 k 大的那個值

  • 我們用三路分區把數分成 < key | == key | > key 三塊。

  • 統計“右邊比 key 大的個數 c”。

    • 如果 k ≤ c:目標還在右邊(更大的區間)。

    • 如果 c < k ≤ c+b:目標就在“等于區間” ? 直接返回 key

    • 如果 k > c+b:說明第 k 大在左邊(更小區間),這時要去左邊繼續找,并把 k -= (c+b)。

    • 停下條件是:k 落在等于區間,結果就是?key。

常規解法
先排序(升序/降序)再取第 n-k / 第 k-1。

問題分析
完整排序復雜度期望 O(n log n),不滿足題設“期望 O(n)”。

思路轉折
要 O(n) → 只能做快選(QuickSelect)

  • 反復三路分區:把區間按 key 切為 <key | ==key | >key;

  • **找“第 k 大”**時,優先看“右段 >key 的元素個數 c”:

    • 若 k ≤ c → 在右段繼續;

    • 若 k ≤ c + b(b 為等于段個數)→ 直接返回 key;

    • 否則 → 去左段,并把 k -= (c + b)(因為這 c+b 個更大的已經被排除在前面)。

1.2 解法

算法思想

三路分區 + 定位“第 k 大”。設

  • b = right - left - 1(等于段大小),

  • c = r - right + 1(大于段大小)。
    決策:

  • k ≤ c → 右段;

  • k ≤ c + b → 返回 key;

  • 否則 → 左段,k = k - (c + b)。

為什么要 k -= (c + b)?

因為遞到左段時,前 c + b 個“更大或相等”的元素已經占據了前面的排名,左段內部要找的目標排名相應向前平移。

i)在 [l..r] 內隨機取樞軸 key。

ii)三路分區得到三段的邊界與大小 b,c。

iii)依據 k 與 c,c+b 的比較,縮小到對應子區間;如進左段要更新 k。

iiii)當命中等于段(k ≤ c + b 且 k > c),返回 key。

易錯點 / 踩坑點

  • while (i < right);在 >key 分支交換到 --right 時不要移動 i。

  • 段大小別算錯:b = right - left - 1,c = r - right + 1。

  • 遞左段要 k -= (c + b);忘了減會錯位。

  • 隨機下標要含右端點:nextInt(l, r + 1);

  • 缺少遞歸基判斷(l == r)?會引發 bound must be positive。

1.3 代碼實現

import java.util.concurrent.ThreadLocalRandom;class Solution {public int findKthLargest(int[] nums, int k) {return qselect(nums, 0, nums.length - 1, k);}// 三路快選:找第 k 大(k 從 1 開始)private static int qselect(int[] nums, int l, int r, int k) {if (l == r) return nums[l];int left = l - 1, right = r + 1, i = l;int key = nums[ThreadLocalRandom.current().nextInt(l, r + 1)];// 三路分區:<key | ==key | >keywhile (i < right) {if (nums[i] < key) {swap(nums, ++left, i++);} else if (nums[i] > key) {swap(nums, --right, i); // i 不動} else {i++;}}// [l, left] < key; [left+1, right-1] == key; [right, r] > keyint b = right - left - 1;   // 等于段int c = r - right + 1;      // 大于段(更大)if (k <= c) {return qselect(nums, right, r, k);            // 在 >key 段} else if (k <= c + b) {return key;                                    // 落在 ==key 段} else {return qselect(nums, l, left, k - (c + b));    // 去 <key 段}}private static void swap(int[] a, int x, int y) {int t = a[x]; a[x] = a[y]; a[y] = t;}
}

復雜度分析

  • 時間:期望 O(N)(隨機樞軸,幾何級縮小)。

  • 空間:O(1) 額外空間

2. 庫存管理III

LCR 159. 庫存管理 III - 力扣(LeetCode)

倉庫管理員以數組?stock?形式記錄商品庫存表,其中?stock[i]?表示對應商品庫存余量。請返回庫存余量最少的?cnt?個商品余量,返回?順序不限

示例 1:

輸入:stock = [2,5,7,4], cnt = 1
輸出:[2]

示例 2:

輸入:stock = [0,2,3,6], cnt = 2
輸出:[0,2] 或 [2,0]

提示:

  • 0 <= cnt <= stock.length <= 10000
    0 <= stock[i] <= 10000

2.1 題目解析

題目本質

這是一個 集合選擇問題:不要求有序,只要找出 全局最小的 cnt 個元素

  • 用三路分區分成 < key | == key | > key。

  • 統計左邊 < key 的個數 a、等于區間的個數 b。

    • 如果 a ≥ k:目標全在左邊,繼續遞歸左段。

    • 如果 a < k ≤ a+b:說明“左邊+等于區間”已經覆蓋住前 k 個 ? 可以停

    • 如果 a+b < k:說明左邊和等于區間還不夠 k 個,必須把它們都要了,然后去右邊繼續找剩余 k - (a+b) 個。

    • 停下條件是:最終需要的前 k 個都落在“小于等于區間”里。這時數組前綴 [0..k-1] 就是結果,雖然內部無序,但保證集合正確。

常規解法
整體排序后取前 cnt;或用堆(大根堆容量 cnt)。

問題分析

  • 排序:O(n log n) 不必要地重排全部。

  • 大根堆:O(n log cnt),當 cnt 接近 n 會偏慢。

思路轉折
三路快選(選擇)把“前綴”變成全局最小的 cnt(內部可無序):

  • 三路分區得到 <key(a) | ==key(b) | >key;

  • 判斷是否已經“覆蓋”前綴:當 a + b ≥ cntNeed 時即可停;

  • 若 a ≥ cntNeed → 遞左段;

  • 若 a + b < cntNeed → 遞右段并 cntNeed -= (a + b)。

2.2 解法

算法思想

在 [l..r] 內反復三路分區,每次決定“繼續左/右”或“停”。停下時,數組前綴(全局)即為所需的 cnt 個最小元素(無序)。

i)若 cnt ≤ 0 返回空;若 cnt ≥ n 直接返回拷貝。

ii)l=0, r=n-1, k = cnt(表示“還需收集”的個數)。

iii)三路分區,求 a,b:

  • a ≥ k → 遞左段 [l, left];

  • a + b ≥ k → 停(覆蓋前綴);

  • 否則 → 遞右段 [right, r],k -= (a + b)。

iiii)退出后拷貝前 cnt 個;若需要升序,再對前綴排序。

易錯點 / 踩坑點

  • 停條件:本題要“集合”,正確停在 a + b ≥ k。

    • 僅 a ≥ k 時不要直接停,要繼續遞左段,否則可能錯拿左段里較大的元素。

  • 進入右段時別忘了:k -= (a + b)。

  • while (i < right) + >key 分支 不移動 i。

  • 無需完整排序,退出后直接拷貝前 cnt 即可。

2.3 代碼實現

import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;class Solution {public int[] inventoryManagement(int[] stock, int cnt) {int n = stock.length;if (cnt <= 0) return new int[0];if (cnt >= n) return Arrays.copyOf(stock, n);int l = 0, r = n - 1;int k = cnt; // 還需要的數量while (l <= r) {int left = l - 1, right = r + 1, i = l;int key = stock[ThreadLocalRandom.current().nextInt(l, r + 1)];while (i < right) {if (stock[i] < key) {swap(stock, ++left, i++);} else if (stock[i] > key) {swap(stock, --right, i); // i 不動} else {i++;}}// [l, left] < key; [left+1, right-1] == key; [right, r] > keyint a = left - l + 1;     // <keyint b = right - left - 1; // ==keyif (a >= k) {r = left;                 // 遞左段} else if (a + b >= k) {break;                    // 覆蓋住了前綴,停} else {k -= (a + b);             // 進入右段繼續收集l = right;}}int[] ans = Arrays.copyOf(stock, cnt); // 無序即可// 若需要升序:Arrays.sort(ans);return ans;}private static void swap(int[] a, int x, int y) {int t = a[x]; a[x] = a[y]; a[y] = t;}
}

復雜度分析

  • 時間:期望 O(n);

  • 空間:O(1) 額外空間。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97228.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97228.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97228.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

10分鐘快速搭建 SkyWalking 服務

從 0 開始入門 SkyWalking&#xff0c;搭建 SkyWalking 服務&#xff0c;并接入 Java 項目中實現分布式鏈路追蹤。 Tags 目錄&#xff1a; 1. 概述2. 搭建 SkyWalking 單機環境3. 搭建 SkyWalking 集群環境4. 告警5. 注意事項6. Spring Boot 使用示例 1. 概述 1.1 概念 …

IDEA之GO語言開發

最近因為接到了需求&#xff0c;說是先把目前公司的JAVA服務慢慢替換成GO語言&#xff0c;于是去了解了一下。 但在開發之前&#xff0c;因為用習慣了IDEA&#xff0c;就想著能不能在IDEA上進行開發&#xff0c;結果真讓我找到了。 作為學習記錄一下 注意&#xff1a;基于IDEA…

rapid_table v3.0.0發布了

更新日志 rapid_table v3.0.0 主要更新是支持 batch 推理&#xff0c;模型并沒有升級哈&#xff01; 因為版本號是根據語義化版本號來走的&#xff0c;這次更改了接口的返回值。因此從 v2.0.3 升級到了 v3.0.0。 返回值具體變化如下&#xff1a; # v2.0.3 class RapidTableO…

若依微服務一鍵部署(RuoYi-Cloud):Nacos/Redis/MySQL + Gateway + Robot 接入(踩坑與修復全記錄)

本文記錄我把 高仙&#xff08;Gaussian&#xff09;機器人對接項目 從“本機能跑”遷到 Docker 一鍵部署 的全過程&#xff1a; 包含 四個后端服務&#xff08;gateway/auth/system/robot&#xff09;、前端 Nginx、MySQL/Redis、Nacos 配置中心、Sentinel 控制臺 的改造要點、…

React 業務場景使用相關封裝(hooks 使用)

React 業務場景相關方法封裝&#xff08;hooks 使用&#xff09; React 中常用的三方 hooks 庫 庫名特點常見場景官方文檔ahooks&#xff08;阿里出品&#xff09;豐富實用的 Hooks&#xff0c;和 Ant Design 配合最佳useRequest&#xff08;請求管理&#xff09;、useDeboun…

[高并發系統設計] - 搭建高并發高可用的系統 - 學習與探究

1.應用場景 主要用于高并發系統設計的架構演進和架構思路。 2.學習/操作 1.文檔閱讀 搭建高并發、高可用的系統 | Laravel China 社區 高并發&#xff0c; 你真的理解透徹了嗎&#xff1f; - 知乎 PHP實戰經驗之系統如何支撐高并發-51CTO.COM PHP高并發和大流量解決方案整理 …

【小白筆記】Visual Studio 在 2025年7月更新的功能說明(英文單詞記憶)

這是NVIDIA軟件中關于數據收集&#xff08;Usage Collection&#xff09;的選項。術語解釋NVIDIA Nsight Visual Studio Edition&#xff1a;這是一款由NVIDIA開發的工具&#xff0c;專門用于在Visual Studio這個集成開發環境&#xff08;IDE&#xff09;中進行GPU調試和性能分…

THM Whats Your Name WP

信息收集[2025-08-28 21:41:30] [SUCCESS] 端口開放 10.10.208.188:80[2025-08-28 21:41:30] [SUCCESS] 端口開放 10.10.208.188:22[2025-08-28 21:41:31] [SUCCESS] 端口開放 10.10.208.188:8081[2025-08-28 21:41:31] [SUCCESS] 服務識別 10.10.208.188:22 > [ssh] 版本:8…

MySQL底層數據結構與算法淺析

1、概述 MySQL中&#xff0c;當我們發現某個sql的執行時間很長時&#xff0c;最先想到的就是給表加索引&#xff0c;加了索引之后&#xff0c;查詢性能就會有顯著的提升。 為了知其所以然&#xff0c;那么只有去了解MySQL的底層儲存結構和索引的查詢算法&#xff0c;只有這樣才…

VisualStudio 將xlsx文件嵌入到資源中訪問時變String?

如題&#xff0c;就是這么詭異&#xff0c;時至如今已經是visual studio 2022了&#xff0c;你通過界面導入xlsx文件到資源中&#xff0c;它的類型就是String而且沒法修改! 即使將文件壓縮成zip再導入&#xff0c;依然是String&#xff01; 三哥的騷操作問你服不服! 然而&#…

【視頻講解】R語言海七鰓鰻性別比分析:JAGS貝葉斯分層邏輯回歸MCMC采樣模型應用

全文鏈接&#xff1a;https://tecdat.cn/?p43774 原文出處&#xff1a;拓端抖音號拓端tecdat 分析師&#xff1a;Yifei Liu 【視頻講解】R語言海七鰓鰻性別比分析&#xff1a;JAGS貝葉斯分層邏輯回歸引言&#xff1a;生態人都懂的痛——樣本少、結果被質疑&#xff0c;咋辦&am…

Android14 USB子系統的啟動以及動態切換相關的init.usb.rc詳解

init.usb.rc的作用是在Android系統啟動和運行時&#xff0c;通過監聽屬性&#xff08;sys.usb.config和sys.usb.configfs, sys.usb.typec.mode&#xff09;變化動態&#xff0c;通過寫入內核接口 /sys/class/android_usb/ 來配置USB模式。1 USB子系統的啟動1.1 on init階段的配…

宜春城區SDH網圖分析

一、SDH網圖展示 圖片來源&#xff1a; 本地網傳輸網組SDH網圖(2014年12月) - 百度文庫 SDH就是Synchronous Digital Hierarchy&#xff0c;同步數字體系的意思。 從分布圖可以看出&#xff0c;城區網和工業網一樣&#xff0c;是環狀結構&#xff0c;保障數據傳輸的穩定。我的…

lwIP MQTT 心跳 Bug 分析與修復

一、背景在使用 lwIP 內置 MQTT 客戶端時&#xff0c;如果你用的是 2.2.0 之前的版本&#xff0c;很可能會遇到一個惱人的問題&#xff1a;客戶端和服務器正常連接&#xff0c;但一段時間后 會話被 broker 踢掉。比如常見的現象&#xff1a;Mosquitto / EMQX 日志顯示客戶端超時…

Golang 面試題「中級」

以下是 100 道 Golang 中級面試題及答案&#xff0c;涵蓋并發編程、內存管理、接口實現、標準庫深入應用等核心知識點&#xff1a; 一、并發編程基礎與進階問題&#xff1a;Golang 的 GPM 調度模型中&#xff0c;G、P、M 分別代表什么&#xff1f;它們的協作關系是怎樣的&#…

沃爾瑪AI系統Wally深度拆解:零售業庫存周轉提速18%,動態定價爭議與員工轉型成熱議點

最近去沃爾瑪購物&#xff0c;發現以前總斷貨的那款早餐麥片居然常年擺在最顯眼的貨架上&#xff0c;而且價格每周末都會微調——這可不是巧合&#xff0c;背后藏著零售業最硬核的AI操作。沃爾瑪去年推出的智能系統Wally&#xff0c;正悄悄改變著我們買東西的體驗和商家的運營邏…

AutoDL算力云上傳文件太慢了如何解決?

----------------------------------------------------------------------------------------------- 這是我在我的網站中截取的文章&#xff0c;有更多的文章歡迎來訪問我自己的博客網站rn.berlinlian.cn&#xff0c;這里還有很多有關計算機的知識&#xff0c;歡迎進行留言或…

【智慧城市】2025年中國地質大學(武漢)暑期實訓優秀作品(2):智慧城市西安與一帶一路

PART 01 項目背景01政策與時代背景近年來&#xff0c;隨著科技的飛速發展和政策的積極推動&#xff0c;我國新型智慧城市建設取得了顯著成效。在“十四五”國家信息化規劃中&#xff0c;明確提出要打造智慧高效的城市治理體系&#xff0c;推動城市管理精細化、服務智能化。同時…

MySQL數據庫精研之旅第十四期:索引的 “潛規則”(上)

專欄&#xff1a;MySQL數據庫成長記 個人主頁&#xff1a;手握風云 目錄 一、索引簡介 1.1. 索引是什么 1.2. 為什么需要索引 二、索引應該選擇哪種數據結構 2.1. Hash 2.2. 二叉搜索樹 2.3. N叉樹 2.4. B樹 三、MySQL中的頁 3.1. 為什么要使用頁 3.2. 頁文件頭和頁…

架構設計——云原生與分布式系統架構

** 云原生與分布式系統架構** 5.1 云選型策略&#xff1a;多云、混合云還是單云&#xff1f;如何決定&#xff1f; “上云”已無需討論&#xff0c;但“上什么云”是第一個戰略決策。單云&#xff08;Single Cloud&#xff09;策略&#xff1a; 描述&#xff1a; 將全部資源集中…