LeetCode --- 444 周賽

題目列表

3507. 移除最小數對使數組有序 I
3508. 設計路由器
3509. 最大化交錯和為 K 的子序列乘積
3510. 移除最小數對使數組有序 II

一、移除最小數對使數組有序 I & II

在這里插入圖片描述

由于數組是給定的,所以本題的操作步驟是固定的,我們只要能快速模擬操作的過程即可
i 、 j i、j ij 為當前進行了操作之后的一對相鄰元素下標

  • 如何快速找到 n u m s [ i ] nums[i] nums[i] 左右兩邊相鄰的 n u m s [ l ] 、 n u m s [ r ] nums[l]、nums[r] nums[l]nums[r]

    • 思路一:維護下標的有序集合,當我們進行合并 n u m s [ i ] 、 n u m s [ j ] ( i < j ) nums[i]、nums[j]\ (i<j) nums[i]nums[j]?(i<j)時 ,刪除 j j j,保留 i i i,當我們要查找 i i i 左右兩邊的相鄰元素時,就去二分查找答案,可以用 s e t set set 維護
    • 思路二:用數組模擬雙向鏈表的增刪查改操作,即維護數組 l e f t [ i ] 、 r i g h t [ i ] left[i]、right[i] left[i]right[i],分別記錄 i i i 左右兩邊的元素下標
  • 如何快速的找到和最小的 n u m s [ i ] 、 n u m s [ j ] ? nums[i]、nums[j]? nums[i]nums[j]

    • 可以用最小堆記錄 p a i r { n u m s [ i ] + n u m s [ j ] , i } pair\{nums[i]+nums[j],i\} pair{nums[i]+nums[j],i},這里的 i i i 為數對下標中較小的那個,即 i < j i<j i<j
    • 當我們將 n u m s [ i ] 、 n u m s [ j ] nums[i]、nums[j] nums[i]nums[j] 跟新為 n u m s [ i ] + n u m s [ j ] nums[i]+nums[j] nums[i]+nums[j] (記為 s s s)時,不僅需要向堆中添加 { n u m s [ l ] + s , l } 、 { s + n u m s [ r ] , i } \{nums[l]+s,l\}、\{s+nums[r],i\} {nums[l]+s,l}{s+nums[r],i},還需要從堆中刪除 { n u m s [ l ] + n u m s [ i ] , l } 、 { n u m s [ i + 1 ] + n u m s [ r ] , j } \{nums[l]+nums[i],l\}、\{nums[i+1]+nums[r],j\} {nums[l]+nums[i],l}{nums[i+1]+nums[r],j},需要用到懶刪除的技巧
    • 如果不會懶刪除技巧,可以用有序集合 s e t set set 來模擬實現懶刪除堆

代碼如下

// C++
class Solution {
public:int minimumPairRemoval(vector<int>& nums) {int n = nums.size();vector<int> left(n, -1), right(n + 1, n); // 模擬雙向鏈表priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;int cnt = 0; //  記錄 nums[i] > nums[i+1] 的個數,以此來判斷數組是否是非遞減的// 初始化for(int i = 0; i < n; i++){right[i] = i + 1;if(i + 1 < n) {left[i+1] = i;pq.emplace(nums[i] + nums[i+1], i);cnt += nums[i] > nums[i + 1];}}int step = 0;while(cnt > 0){// 懶刪除// right[pq.top().second] >= n 表示當前 pq.top().second 已經被合并后刪除// pq.top().first != nums[pq.top().second] + nums[right[pq.top().second]] 表示 nums[right[pq.top().second]] 已經被合并過了while(right[pq.top().second] >= n || pq.top().first != nums[pq.top().second] + nums[right[pq.top().second]]){pq.pop();}auto [s, i] = pq.top(); pq.pop();int l = left[i], j = right[i], r = right[j]; // l,i,j,r 之間的大小關系發生變化// 由于 i、j 要合并,先去掉之前的大小關系if(nums[i] > nums[j]) cnt--;if(l != -1 && nums[l] > nums[i]) cnt--;if(r != n && nums[j] > nums[r]) cnt--;// 加入新的大小關系if(l != -1 && nums[l] > s) cnt++;if(r != n && s > nums[r]) cnt++;// 如果 i 的前面有數字,則將{nums[l]+s,l}加入堆中if(l != -1){pq.emplace(s + nums[l], l);}// 如果 i 的后面有數字,則將{nums[r]+s,r}加入堆中if(r != n){pq.emplace(s + nums[r], i);}// 刪除 j 結點,保留 i 結點// 讓 i -> r, r -> i// 同時讓 j -> n 表示 結點 j 被刪除if(j < n) right[i] = right[j], right[j] = n;if(r < n) left[r] = i;nums[i] = s; // 跟新當前合并之后的值step++;}return step;}
};

二、設計路由器

在這里插入圖片描述
本題關鍵理解題意,抽象出我們需要使用的數據結構

  • i n t [ ] f o r w a r d P a c k e t ( ) int[]\ \ forwardPacket() int[]??forwardPacket() 需要先進先出:需要有一個 q u e u e queue queue
  • b o o l a d d P a c k e t ( i n t s o u r c e , i n t d e s t i n a t i o n , i n t t i m e s t a m p ) bool\ \ addPacket(int\ \ source, int\ \ destination, int\ \ timestamp) bool??addPacket(int??source,int??destination,int??timestamp) 要求不能重復插入相同的數據包:需要一個哈希表 u n o r d e r e d _ s e t unordered\_set unordered_set,記錄插入過的數據包
  • i n t g e t C o u n t ( i n t d e s t i n a t i o n , i n t s t a r t T i m e , i n t e n d T i m e ) int\ \ getCount(int\ \ destination, int\ \ startTime, int\ \ endTime) int??getCount(int??destination,int??startTime,int??endTime) 獲取尚未轉發的時間在 [ s t a r t T i m e , e n d T i m e ] [startTime,endTime] [startTime,endTime] 中,且目標為 d e s t i n a t i o n destination destination 的數據包的個數:這里我們可以把 d e s t i n a t i o n destination destination 相同的數據包放在一個數組中,由于數據包是按照時間順序插入的,我們可以用二分法,獲取區間內的數據包個數,即額外維護一個 u n o r d e r e d _ m a p < i n t , v e c t o r < i n t > > unordered\_map<int,vector<int>> unordered_map<int,vector<int>>

代碼如下

class Router {unordered_map<int,vector<int>> d_t; // [d, vt]// 這里使用循環數組模擬隊列vector<tuple<int,int,int>> v;int l = 0, r = 0;unordered_set<string> st;
public:Router(int memoryLimit) : v(memoryLimit + 1) {}bool addPacket(int s, int d, int t) {string mask = to_string(s) + '|' +  to_string(d) + '|' + to_string(t);if(st.count(mask)) return false;st.insert(mask);if((r + 1)%v.size() == l){ // 隊列滿auto [ss, dd, tt] = v[l++];l %= v.size();st.erase(to_string(ss) + '|' + to_string(dd) + '|' + to_string(tt));d_t[dd].erase(d_t[dd].begin());}d_t[d].push_back(t);v[r++] = {s, d, t};r %= v.size();return true;}vector<int> forwardPacket() {if(r == l) return {}; // 隊列為空auto [s, d, t] = v[l++];l %= v.size();d_t[d].erase(d_t[d].begin());st.erase(to_string(s) + '|' + to_string(d) + '|' + to_string(t));return {s, d, t};}int getCount(int d, int startTime, int endTime) {auto& v = d_t[d];return ranges::upper_bound(v, endTime) - ranges::lower_bound(v, startTime);}
};

三、最大化交錯和為 K 的子序列乘積

在這里插入圖片描述
本題只需要暴搜即可,因為狀態的個數并沒有我們想象的那么多

  • 狀態定義為 d f s ( i , s , m , o p , e m p t y ) dfs(i,s,m,op,empty) dfs(i,s,m,op,empty)

    • i i i 表示枚舉的數字下標
    • s s s 表示交錯和
    • m m m 表示子序列的元素乘積
    • o p op op 表示當前元素是取正,還是取負
    • e m p t y empty empty 表示子序列是否為空
  • 有人可能覺得這個狀態太多了,肯定會超時
    在這里插入圖片描述
    因為 m m m 的取值范圍是 [ 1 , 5000 ] [1,5000] [1,5000],但實際上,在當前的數據范圍內 m m m 最多只有 394 + 1 394+1 394+1 種可能取值( + 1 +1 +1 表示當子序列中有 0 0 0 時,乘積為 0 0 0),可以通過如下代碼進行驗證

int init = [](){set<int> st{1};for(int i = 0; i < 150; i++){ // 150 個值auto tmp = st;for(auto x : st){for(int i = 1; i <= 12; i++){ // 每個值有可以取 1~12if(x * i <= 5000){st.insert(x * i);}}}}cout << st.size() << endl;return 0;
}();

代碼如下

class Solution {
public:int maxProduct(vector<int>& nums, int k, int limit) {int total = reduce(nums.begin(), nums.end());if (total < abs(k)) { // |k| 太大return -1;}int n = nums.size(), ans = -1;unordered_set<long long> vis;auto dfs = [&](this auto&& dfs, int i, int s, int m, bool op, bool empty) -> void {// 無法讓 ans 變得更大// 注意:當 m > limit && ans < 0 時,如果在選擇一個0,既能讓 m < limt,ans = 0if (ans == limit || m > limit && ans >= 0) { return;}if (i == n) {if (!empty && s == k && m <= limit) { // 合法子序列ans = max(ans, m); // 更新答案的最大值}return;}long long mask = (long long) i << 32 | (s + total) << 15 | m << 2 | op << 1 | empty;if (!vis.insert(mask).second) {return;}// 不選 xdfs(i + 1, s, m, op, empty);// 選 xint x = nums[i];dfs(i + 1, s + (op ? -x : x), min(m * x, limit + 1), !op, false);};dfs(0, 0, 1, false, true);return ans;}
};

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

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

相關文章

限流、降級、熔斷、隔離?

在微服務架構中&#xff0c;服務限流、降級、熔斷和隔離是保障系統高可用性的核心手段&#xff0c;但它們解決的問題和應用場景不同。以下是它們的區別、解決方案和實際案例的詳細說明&#xff1a; 一、服務限流&#xff08;Rate Limiting&#xff09; 定義&#xff1a;通過限…

Day22 -php開發01--留言板+知識點(超全局變量 文件包含 數據庫操作 第三方插件)

環境要求&#xff1a;php7.0.9 小皮 navicat phpstorm24.1 知識點&#xff1a;會寫&#xff08;留言板 留言板后臺&#xff09; 超全局變量 三方插件的使用 文件包含 1、開啟小皮并利用navicat新建一個數據庫 注意&#xff1a;本地的服務mysql關閉后 才可打開小皮。屬…

制造一只電子喵 (qwen2.5:0.5b 微調 LoRA 使用 llama-factory)

AI (神經網絡模型) 可以認為是計算機的一種新的 “編程” 方式. 為了充分利用計算機, 只學習傳統的編程 (編程語言/代碼) 是不夠的, 我們還要掌握 AI. 本文以 qwen2.5 和 llama-factory 舉栗, 介紹語言模型 (LLM) 的微調 (LoRA SFT). 為了方便上手, 此處選擇使用小模型 (qwen2…

LeetCode 解題思路 37(Hot 100)

解題思路&#xff1a; 初始化&#xff1a; 初始化最大舉行 max 和棧 stack。左右補零&#xff1a; 考慮柱子遞增的邊界情況&#xff0c; 初始化填充柱狀圖 newHeights。遍歷處理&#xff1a; 對于每一根遍歷到的柱子 newHeights[i]&#xff0c;若柱子高度小于棧口索引&#xf…

HTML — 過渡與動畫

HTML過渡與動畫是提升網頁交互體驗的核心技術&#xff0c;主要通過CSS實現動態效果。 過渡 CSS過渡&#xff08;Transition&#xff09;介紹 適用于元素屬性變化時的平滑漸變效果&#xff0c;如懸停變色、尺寸調整。通過定義transition-property&#xff08;過渡屬性&#xf…

跨站請求是什么?

介紹 跨站請求&#xff08;Cross-Site Request&#xff09;通常是指瀏覽器在訪問一個網站時&#xff0c;向另一個域名的網站發送請求的行為。這個概念在 Web 安全中非常重要&#xff0c;尤其是在涉及到“跨站請求偽造&#xff08;CSRF&#xff09;”和“跨域資源共享&#xff…

Web攻防—SSRF服務端請求偽造Gopher偽協議無回顯利用

前言 重學Top10的第二篇&#xff0c;希望各位大佬不要見笑。 SSRF原理 SSRF又叫服務端請求偽造&#xff0c;是一種由服務端發起的惡意請求&#xff0c;SSRF發生在應用程序允許攻擊者誘使服務器向任意域或資源發送未經授權的請求時。服務器充當代理&#xff0c;執行攻擊者構造…

Hibernate:讓對象與數據庫無縫對話的全自動ORM框架

一、為什么需要全自動ORM&#xff1f; 在手動編寫SQL的時代&#xff0c;開發者需要在Java代碼和數據庫表之間來回切換&#xff1a; // Java對象 public class User {private Long id;private String name;// getters and setters }// SQL語句 SELECT * FROM user WHERE id ?…

C語言超詳細指針知識(一)

通過前面一段時間C語言的學習&#xff0c;我們了解了數組&#xff0c;函數&#xff0c;操作符等的相關知識&#xff0c;今天我們將要開始進行指針的學習&#xff0c;這是C語言中較難掌握的一個部分&#xff0c;一定要認真學習&#xff01;&#xff01;&#xff01; 1.內存與地址…

程序化廣告行業(70/89):ABTester系統助力落地頁優化實踐

程序化廣告行業&#xff08;70/89&#xff09;&#xff1a;ABTester系統助力落地頁優化實踐 在程序化廣告領域摸爬滾打多年&#xff0c;深知持續學習和知識共享的重要性。寫這篇博客&#xff0c;就是希望能和大家一起深入探索程序化廣告行業&#xff0c;共同學習、共同進步。今…

項目管理(高軟56)

系列文章目錄 項目管理 文章目錄 系列文章目錄前言一、進度管理二、配置管理三、質量四、風險管理五、真題總結 前言 本節主要講項目管理知識&#xff0c;這些知識聽的有點意思啊。對于技術人想創業&#xff0c;單干的都很有必要聽聽。 一、進度管理 二、配置管理 三、質量 四…

常見的后綴名

.exe .exe&#xff08;“executable”&#xff08;可執行的&#xff09;&#xff09;是 Windows 操作系統中最常見的可執行文件擴展名。此類文件包含了計算機能夠直接運行的機器碼指令。當用戶雙擊 .exe 文件時&#xff0c;操作系統會讀取其中的指令并執行相應的程序或任務。…

XILINX DDR3專題---(1)IP核時鐘框架介紹

1.什么是Reference Clock&#xff0c;這個時鐘一定是200MHz嗎&#xff1f; 2.為什么APP_DATA是128bit&#xff0c;怎么算出來的&#xff1f; 3.APP &#xff1a;MEM的比值一定是1:4嗎&#xff1f; 4.NO BUFFER是什么意思&#xff1f; 5.什么情況下Reference Clock的時鐘源可…

Doris 安裝部署、實際應用及優化實踐:對比 ClickHouse 的深度解析

在實時分析、報表系統以及高并發 OLAP 查詢等場景中&#xff0c;列式存儲數據庫因其卓越的查詢性能逐漸成為主流。Doris 和 ClickHouse 是近年來最受歡迎的兩款開源 OLAP 引擎&#xff0c;本文將系統介紹 Doris 的安裝部署、應用場景及優化實踐&#xff0c;并與 ClickHouse 做一…

OracleLinuxR5U5系統重啟后啟動數據庫oracle23ai

1、切換到oracle用戶 [rootOracleLinux-R9-U5 ~]# su oracle2、查看oracle是否配置了ORACLE_SID [oracleOracleLinux-R9-U5 root]$ cd ~ [oracleOracleLinux-R9-U5 ~]$ cat .bash_profile3、輸出內容如下&#xff1a; [oracleOracleLinux-R9-U5 ~]$ cat .bash_profile # .ba…

【正點原子】STM32MP257 同構多核架構下的 ADC 電壓采集與處理應用開發實戰

在嵌入式系統中&#xff0c;ADC模擬電壓的讀取是常見的需求。如何高效、并發、且可控地完成數據采集與處理&#xff1f;本篇文章通過雙線程分別綁定在 Linux 系統的不同 CPU 核心上&#xff0c;采集 /sys/bus/iio 接口的 ADC 原始值與縮放系數 scale&#xff0c;并在另一個核上…

電商用戶購物行為分析:基于K-Means聚類與分類驗證的完整流程

隨著電商行業的快速發展,用戶行為分析成為企業優化營銷策略、提升用戶體驗的重要手段。通過分析用戶的購物行為數據,企業可以挖掘出用戶群體的消費特征和行為模式,從而制定更加精準的營銷策略。本文將詳細介紹一個基于Python實現的電商用戶購物行為分析系統,涵蓋數據預處理…

AMGCL庫的Backends及使用示例

AMGCL庫的Backends及使用示例 AMGCL是一個用于解決大型稀疏線性方程組的C庫&#xff0c;它提供了多種后端(backends)實現&#xff0c;允許用戶根據不同的硬件和性能需求選擇合適的計算后端。 AMGCL支持的主要Backends 內置Backends: builtin - 默認的純C實現block - 支持塊狀…

Express中間件(Middleware)詳解:從零開始掌握(3)

實用中間件模式25例 1. 基礎增強模式 請求屬性擴展 function extendRequest() {return (req, res, next) > {req.getClientLanguage () > {return req.headers[accept-language]?.split(,)[0] || en;};next();}; } 響應時間頭 function responseTime() {return (r…

05--MQTT物聯網協議

一、MQTT的概念 MQTT 協議快速入門 2025&#xff1a;基礎知識和實用教程 | EMQ 1.MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一種輕量級、基于發布-訂閱模式的消息傳輸協議&#xff0c;適用于資源受限的設備和低帶寬、高延遲或不穩定的網絡環境。它…