每日算法-250328

記錄今天學習和解決的LeetCode算法題。


92. 反轉鏈表 II

題目

Problem 92 Description

思路

本題要求反轉鏈表中從 leftright 位置的節點。我們可以采用 頭插法 的思路來反轉指定區間的鏈表。

具體來說,我們首先定位到 left 位置節點的前一個節點 prev。然后,從 left 位置開始,依次將 left + 1right 位置的節點移動到 prev 節點的后面,也就是反轉區間的“頭部”。

解題過程

  1. 虛擬頭節點 (Dummy Node): 為了方便處理 left = 1 的情況(即反轉從頭節點開始),我們創建一個虛擬頭節點 dummy,并讓 dummy.next 指向原始鏈表的頭節點 head。最終返回結果時返回 dummy.next

  2. 定位 prev 節點: 我們需要找到反轉區間的前一個節點,記為 prev。通過一個循環,將 prev 指針從 dummy 開始向后移動 left - 1 步,使其指向第 left - 1 個節點。

  3. 定位 cur 節點: cur 指針初始化為 prev.next,即反轉區間的第一個節點(第 left 個節點)。

  4. 執行反轉 (頭插法): 進行 right - left 次操作。在每次操作中:

    • 記錄 cur 的下一個節點,記為 curNext。這curNext 就是本次需要移動到反轉區間頭部的節點。
    • curnext 指針指向 curNext 的下一個節點,即將 curNext 從鏈表中暫時斷開。 (cur.next = curNext.next;)
    • curNext 插入到 prev 節點的后面:讓 curNextnext 指針指向當前反轉區間的第一個節點 (prev.next)。 (curNext.next = prev.next;)
    • 更新 prevnext 指針,使其指向新插入的 curNext,這樣 curNext 就成為了新的反轉區間的第一個節點。 (prev.next = curNext;)
    • 注意:在這個過程中,cur 指針始終指向原來的第 left 個節點,它在反轉后會成為反轉區間的最后一個節點。 prev 指針始終不變,指向反轉區間的前一個節點。
  5. 返回結果: 所有操作完成后,dummy.next 指向的就是新鏈表的頭節點,返回 dummy.next

復雜度

  • 時間復雜度: O ( n ) O(n) O(n),其中 n n n 是鏈表的長度。需要遍歷鏈表找到 prev 節點,然后進行 right - left 次節點移動操作。
  • 空間復雜度: O ( 1 ) O(1) O(1),只使用了常數級別的額外空間(幾個指針變量)。

Code

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {// 創建虛擬頭節點,簡化邊界處理(如 left=1)ListNode dummy = new ListNode(0);dummy.next = head;// 1. 移動 prev 指針到第 left-1 個節點ListNode prev = dummy;for (int i = 1; i < left; i++) {prev = prev.next;}// 2. cur 指針指向第 left 個節點,即反轉區間的起始節點ListNode cur = prev.next;// 3. 執行頭插法反轉 [left, right] 區間// 進行 right - left 次操作for (int i = left; i < right; i++) {// a. 記錄待移動的節點 curNextListNode curNext = cur.next;// b. cur 指向 curNext 的下一個節點,將 curNext 從鏈表中斷開cur.next = curNext.next;// c. 將 curNext 插入到 prev 之后(成為反轉區間的新頭部)curNext.next = prev.next;// d. 更新 prev 的 next 指針prev.next = curNext;}// 4. 返回新鏈表的頭節點return dummy.next;}
}

1004. 最大連續1的個數 III

題目

Problem 1004 Description

思路

本題可以使用 滑動窗口 的方法解決。

核心思想是維護一個窗口 [left, right],使得這個窗口內包含的 0 的數量不超過 k。在窗口滑動過程中,不斷更新窗口的最大長度。

解題過程

  1. 初始化: 設置窗口左右邊界 left = 0, right = 0,當前窗口內 0 的計數 count = 0,以及最大窗口長度 maxLen = 0
  2. 擴展窗口: 移動 right 指針向右擴展窗口。
    • 如果 nums[right]0,則 count 加 1。
  3. 收縮窗口: 當窗口內 0 的數量 count 超過 k 時,需要收縮窗口。
    • 移動 left 指針向右收縮窗口。
    • 如果移出窗口的元素 nums[left]0,則 count 減 1。
    • 持續收縮直到 count <= k
  4. 更新結果: 在每次窗口調整(擴展或收縮)后,當前窗口 [left, right] 都是一個合法的窗口(0 的數量不超過 k)。計算當前窗口長度 right - left + 1,并更新 maxLen = Math.max(maxLen, right - left + 1)
  5. 遍歷結束: 當 right 指針到達數組末尾時,maxLen 即為所求的最大連續1的個數(允許翻轉 k 個0)。
  6. 返回結果: 返回 maxLen

復雜度

  • 時間復雜度: O ( n ) O(n) O(n),其中 n n n 是數組 nums 的長度。每個元素最多被 leftright 指針訪問一次。
  • 空間復雜度: O ( 1 ) O(1) O(1),只使用了常數級別的額外空間。

Code

class Solution {public int longestOnes(int[] nums, int k) {int maxLen = 0; // 記錄最大窗口長度int zeroCount = 0; // 記錄當前窗口內 0 的個數int left = 0; // 窗口左邊界// right 指針負責擴展窗口for (int right = 0; right < nums.length; right++) {// 如果新進入窗口的元素是 0,增加 zeroCountif (nums[right] == 0) {zeroCount++;}// 當窗口內 0 的數量超過 k 時,收縮窗口while (zeroCount > k) {// 如果移出窗口的元素是 0,減少 zeroCountif (nums[left] == 0) {zeroCount--;}// 移動左邊界left++;}// 此時窗口 [left, right] 是合法的,更新最大長度maxLen = Math.max(maxLen, right - left + 1);}return maxLen;}
}

1658. 將 x 減到 0 的最小操作數

題目

Problem 1658 Description

思路

逆向思維 + 滑動窗口

題目要求從數組兩端移除元素,使得移除元素的和等于 x,并求最小的操作次數(即移除元素的最少數量)。

我們可以反向思考:從兩端移除元素,等價于在數組中間保留一段 連續 的子數組,使得這段子數組的和等于 totalSum - x

那么問題就轉化為:找到數組 nums 中和為 target = totalSum - x最長 連續子數組的長度 maxLen。如果找到了這樣的子數組,則最小操作數就是 n - maxLen(其中 n 是數組總長度)。如果找不到,則說明無法通過移除操作使和為 x,返回 -1

我們可以使用滑動窗口來尋找和為 target 的最長連續子數組。

解題過程

  1. 計算總和: 計算數組 nums 的總和 totalSum
  2. 計算目標和: 計算目標子數組的和 target = totalSum - x
  3. 處理邊界情況:
    • 如果 target < 0,說明 xtotalSum 還大,不可能通過移除元素得到 x,直接返回 -1
    • 如果 target == 0,說明需要移除所有元素,其和才等于 x (x == totalSum)。此時最長子數組長度為 0,操作數為 n - 0 = n
  4. 滑動窗口: 使用滑動窗口尋找和為 target 的最長連續子數組。
    • 初始化 left = 0, currentSum = 0, maxLen = -1 (-1 表示尚未找到滿足條件的子數組)。
    • right 指針遍歷數組,擴展窗口,將 nums[right] 加入 currentSum
    • currentSum > target 時,收縮窗口:從 currentSum 中減去 nums[left],并向右移動 left 指針,直到 currentSum <= target
    • 如果 currentSum == target,說明找到了一個和為 target 的子數組 [left, right]。更新 maxLen = Math.max(maxLen, right - left + 1)
  5. 返回結果:
    • 如果 maxLen 仍然是 -1,說明沒有找到和為 target 的子數組,返回 -1
    • 否則,返回 n - maxLen

復雜度

  • 時間復雜度: O ( n ) O(n) O(n),其中 n n n 是數組 nums 的長度。計算總和需要 O ( n ) O(n) O(n),滑動窗口也需要 O ( n ) O(n) O(n)
  • 空間復雜度: O ( 1 ) O(1) O(1),只使用了常數級別的額外空間。

Code

class Solution {public int minOperations(int[] nums, int x) {int n = nums.length;long totalSum = 0; // 使用 long 防止整數溢出for (int num : nums) {totalSum += num;}// 計算目標子數組的和long target = totalSum - x;// 邊界情況:x 比總和還大,無解if (target < 0) {return -1;}// 邊界情況:x 等于總和,需要移除所有元素if (target == 0) {return n;}int maxLen = -1; // 記錄和為 target 的最長子數組長度,初始化為 -1 表示未找到long currentSum = 0;int left = 0;// 滑動窗口尋找和為 target 的最長子數組for (int right = 0; right < n; right++) {currentSum += nums[right];// 當窗口和大于 target 時,收縮窗口while (currentSum > target && left <= right) {currentSum -= nums[left];left++;}// 如果窗口和等于 target,更新 maxLenif (currentSum == target) {maxLen = Math.max(maxLen, right - left + 1);}}// 如果 maxLen 仍為 -1,說明找不到和為 target 的子數組,返回 -1// 否則,返回 n - maxLenreturn maxLen == -1 ? -1 : n - maxLen;}
}

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

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

相關文章

C語言中的位域:節省內存的標志位管理技術

位域&#xff08;Bit-field&#xff09; 是 C 語言中的一種特性&#xff0c;允許在結構體&#xff08;struct&#xff09;中定義占用特定位數的成員變量。通過位域&#xff0c;可以更精細地控制內存的使用&#xff0c;尤其是在需要存儲多個布爾值或小范圍整數時&#xff0c;可以…

【AI編程學習之Python】第一天:Python的介紹

Python介紹 簡介 Python是一種解釋型、面向對象的語言。由吉多范羅蘇姆(Guido van Rossum)于1989年發明,1991年正式公布。官網:www.python.org Python單詞是"大蟒蛇”的意思。但是龜叔不是喜歡蟒蛇才起這個名字,而是正在追劇:英國電視喜劇片《蒙提派森的飛行馬戲團》(Mo…

【openstack系列】虛擬化技術

OpenStack 是一個開源的云計算管理平臺,它本身并不直接提供虛擬化技術,而是通過集成不同的虛擬化解決方案來管理和編排計算、存儲和網絡資源。OpenStack 的核心優勢在于其靈活性和可擴展性,支持多種虛擬化技術(Hypervisor),使企業可以根據需求選擇合適的底層虛擬化方案。…

保姆級教程:Vue3 + Django + MySQL 前后端聯調(PyCharm+VSCode版)

一、環境準備與驗證 這里為減少篇幅&#xff0c;默認大家都安裝好了這些軟件。不會下載安裝的&#xff0c;教程也很多&#xff0c;這里不再做贅述。話不多說&#xff0c;咱們開始&#xff1a; 1. 安裝驗證 確保已安裝以下軟件并驗證版本&#xff1a; # 驗證Node.js node -v…

Spring Data審計利器:@LastModifiedDate詳解!!!

&#x1f552; Spring Data審計利器&#xff1a;LastModifiedDate詳解&#x1f525; &#x1f31f; 簡介 在數據驅動的應用中&#xff0c;記錄數據的最后修改時間是常見需求。Spring Data的LastModifiedDate注解讓這一過程自動化成為可能&#xff01;本篇帶你掌握它的核心用法…

洛谷題單1-P1001 A+B Problem-python-流程圖重構

題目描述 輸入兩個整數 a,b&#xff0c;輸出它們的和&#xff08;∣a∣,∣b∣≤109&#xff09;。 輸入格式 兩個以空格分開的整數。 輸出格式 一個整數。 輸入輸出樣例 輸入 20 30輸出 50方式-print class Solution:staticmethoddef oi_input():"""從…

CCF CSP 第33次(2024.03)(2_相似度計算_C++)(字符串中字母大小寫轉換+哈希集合)

CCF CSP 第33次&#xff08;2024.03&#xff09;&#xff08;2_相似度計算_C&#xff09; 題目背景&#xff1a;題目描述&#xff1a;輸入格式&#xff1a;輸出格式&#xff1a;樣例1輸入&#xff1a;樣例1輸出&#xff1a;樣例1解釋&#xff1a;樣例2輸入&#xff1a;樣例2輸出…

Windows .gitignore文件不生效的情況排查

概述 今天下班在家里搗騰自己的代碼&#xff0c;在配置.gitignore文件忽略部分文件的時候&#xff0c;發現死活不生效 問題根源 經過一通分析和排查才發現&#xff0c;是.gitignore文件的編碼錯了&#xff0c;剛開始還沒注意到&#xff0c;因為是在Windows下開發&#xff0c…

Uniapp自定義TabBar組件全封裝實踐與疑難問題解決方案

前言 在當前公司小程序項目中&#xff0c;我們遇到了一個具有挑戰性的需求&#xff1a;根據不同用戶身份動態展示差異化的底部導航欄&#xff08;TabBar&#xff09; 。這種多角色場景下的UI適配需求&#xff0c;在提升用戶體驗和實現精細化運營方面具有重要意義。 在技術調研…

四川省汽車加氣站操作工備考題庫及答案分享

1.按壓力容器的設計壓力分為&#xff08; &#xff09;個壓力等級。 A. 三 B. 四 C. 五 D. 六 答案&#xff1a;B。解析&#xff1a;按壓力容器的設計壓力分為低壓、中壓、高壓、超高壓四個壓力等級。 2.緩沖罐的安裝位置在天然氣壓縮機&#xff08; &#xff09;。 A. 出口處 …

2025年- G27-Lc101-542. 01 矩陣--java版

1.題目描述 2.思路 總結&#xff1a;用廣度優先搜索&#xff0c;首先要確定0的位置&#xff0c;不為0的位置&#xff0c;我們要更新的它的值&#xff0c;只能往上下左右尋找跟它最近的0的位置。 解題思路 我們用 BFS&#xff08;廣度優先搜索&#xff09;求解&#xff0c;因為 …

CANopen基本理論

目錄 一、CANopen簡介 二、OD對象字典 2.1 OD對象字典簡介 2.2 CANopen預定義連接集 三、PDO過程數據對象 四、SDO過程數據對象 五、特殊協議 5.1 同步協議 5.2 時間戳協議 5.3 緊急報文協議 六、NMT網絡管理 6.1 NMT節點狀態 6.2 NMT節點上線報文 6.3 NMT心跳報…

【Zookeeper搭建】Zookeeper分布式集群搭建完整指南

Zookeeper分布式集群搭建 &#xff08;一&#xff09;克隆前準備工作 一、時鐘同步 步驟&#xff1a; 1、輸入date命令可以查看當前系統時間&#xff0c;可以看到此時系統時間為PDT&#xff08;部分機器或許為EST&#xff09;&#xff0c;并非中國標準時間。我們在中國地區…

MVC基礎概念及相應代碼示例

&#xff08;舊的&#xff09;代碼實現方法 一個功能模塊的代碼邏輯&#xff08;顯示處理&#xff0c;數據處理&#xff0c;邏輯判定&#xff09;都寫在一起(耦合) &#xff08;新的&#xff09;代碼MVC分層實現方法 顯示部分實現&#xff08;View視圖&#xff09; 數據處理實…

nginx優化(持續更新!!!)

1.調整文件描述符 # 查看當前系統文件描述符限制 ulimit -n# 永久修改文件描述符限制 # 編輯 /etc/security/limits.conf 文件&#xff0c;添加以下內容 * soft nofile 65535 * hard nofile 65535# 編輯 /etc/sysctl.conf 文件&#xff0c;添加以下內容 fs.file-max 655352.調…

apache連接池機制討論

apache連接池的連接有效性 server一般會配置keep-alive超時時間&#xff0c;過了這個時間還沒新請求到來&#xff0c;則關閉連接。客戶端從連接池里拿出連接時&#xff0c;會檢查一下連接是否已關閉&#xff0c;如已關閉&#xff0c;會丟棄掉該連接&#xff0c;并嘗試從連接池…

【QT5 多線程示例】條件變量

文章目錄 條件變量使用 wakeOne()使用 wakeAll() 條件變量 QT的條件變量類是QWaitCondition&#xff0c;有wakeOne() 和 wakeAll() 兩個方法 wakeOne()&#xff1a;僅喚醒一個等待的線程。wakeAll()&#xff1a;喚醒所有等待的線程。 使用 wakeOne() https://github.com/Bi…

備賽藍橋杯之第十六屆模擬賽第1期職業院校組第四題:世紀危機(人口增長推算)

提示&#xff1a;本篇文章僅僅是作者自己目前在備賽藍橋杯中&#xff0c;自己學習與刷題的學習筆記&#xff0c;寫的不好&#xff0c;歡迎大家批評與建議 由于個別題目代碼量與題目量偏大&#xff0c;請大家自己去藍橋杯官網【連接高校和企業 - 藍橋云課】去尋找原題&#xff0…

從零構建大語言模型全棧開發指南:第三部分:訓練與優化技術-3.2.3預訓練任務設計:掩碼語言建模(MLM)與下一句預測(NSP)

?? 點擊關注不迷路 ?? 點擊關注不迷路 ?? 點擊關注不迷路 文章大綱 3.2.3 預訓練任務設計:`掩碼語言建模(MLM)`與下一句預測(NSP)1. 掩碼語言建模(`Masked Language Modeling, MLM`)1.1 MLM的核心原理與數學形式1.2 高級掩碼優化技術1.2.1 `Span Masking(SpanBER…

OpenBMC:BmcWeb 生效路由2 Trie字典樹

OpenBMC:BmcWeb 生效路由1 基于method分類路由_openbmc web-CSDN博客 可以看到,在internalAdd中: std::vector<BaseRule*> rules; rules.emplace_back(ruleObject); trie.add(rule, static_cast<unsigned>(rules.size() - 1U)); ruleObject首先被放入了每個meth…