【LeetCode 熱題 100】32. 最長有效括號——(解法二)動態規劃

Problem: 32. 最長有效括號

文章目錄

  • 整體思路
  • 完整代碼
  • 時空復雜度
    • 時間復雜度:O(N)
    • 空間復雜度:O(N)

整體思路

這段代碼同樣旨在解決 “最長有效括號” 問題,但它采用的是一種 動態規劃 (Dynamic Programming) 的方法。這種方法通過構建一個DP表(dp 數組),從左到右逐步計算以每個字符為結尾的最長有效括號子串的長度。

算法的核心在于定義狀態 dp[i] 并找出其狀態轉移關系。

  1. 狀態定義

    • dp[i] 被定義為:以字符串 s 中第 i-1 個字符(即 s.charAt(i-1))為結尾的最長有效括號子串的長度
    • 索引偏移:為了方便處理邊界,代碼在原始字符串 s 前面加了一個空格 " ",使得 s 的索引從1開始。這樣,dp 數組的索引 i 就直接對應了新字符串的索引 i
  2. 狀態轉移方程

    • dp[i] 的值只有在 s.charAt(i) 是一個右括號 ')' 時才可能大于0,因為一個有效的括號子串必然以 ')' 結尾。如果 s.charAt(i)'('dp[i] 默認為0。
    • s.charAt(i) == ')' 時,我們需要尋找一個與之匹配的左括號 '('。這里有兩種主要情況:
      a. 情況 1:形如 ...()
      • 如果 s.charAt(i-1) 是一個 '(',那么 s.charAt(i)s.charAt(i-1) 構成了最簡單的一對有效括號 ()
      • 這個 () 的長度是 2。它還可以連接在 s.charAt(i-2) 結尾的有效子串后面。
      • 因此,狀態轉移方程為:dp[i] = dp[i-2] + 2
        b. 情況 2:形如 ...))
      • 如果 s.charAt(i-1) 也是一個 ')',那么 s.charAt(i) 需要去匹配更左邊的某個 '('
      • 我們知道,以 s.charAt(i-1) 結尾的有效子串長度是 dp[i-1]。那么,這個子串的起始位置就是 i - 1 - dp[i-1] + 1。它所需要匹配的左括號就在這個起始位置的前一個,即索引 i - 1 - dp[i-1] 的位置。
      • 我們檢查 s.charAt(i - 1 - dp[i-1]) 是否為 '('
      • 如果匹配成功
        • 新形成的這個大括號 (...) 的長度是 dp[i-1] + 2
        • 并且,這個大括號還可以連接在它前面的另一個有效子串后面。這個“前面的有效子串”是以 s.charAt(i - 2 - dp[i-1]) 結尾的,其長度為 dp[i - 2 - dp[i-1]]
        • 因此,總長度為:dp[i] = dp[i-1] + 2 + dp[i - 2 - dp[i-1]]
  3. 最終結果

    • 在填充 dp 數組的過程中,dp[i] 只是以 s.charAt(i) 為結尾的最長長度。全局的最長長度可能是任何一個 dp[i] 的值。
    • 因此,需要一個 ans 變量來實時記錄并更新所有 dp[i] 中的最大值。

完整代碼

class Solution {/*** 找到字符串中最長的有效括號子串的長度。* @param s 只包含 '(' 和 ')' 的字符串* @return 最長有效括號子串的長度*/public int longestValidParentheses(String s) {// ans: 用于存儲全局的最長有效括號子串長度。int ans = 0;// 技巧:在 s 前面加一個空格,使得索引從 1 開始,方便處理邊界情況 dp[i-2]。s = " " + s;// dp 數組:dp[i] 表示以 s.charAt(i) 結尾的最長有效括號子串的長度。int[] dp = new int[s.length()];// 從索引 2 開始遍歷,因為最短的有效括號 "()" 長度為 2。for (int i = 2; i < s.length(); i++) {// 只在遇到右括號時才可能形成有效子串if (s.charAt(i) == ')') {// 情況 1: 子串形如 ".....()"if (s.charAt(i - 1) == '(') {// 長度 = 前面有效子串的長度 (dp[i-2]) + "()" 的長度 (2)dp[i] = dp[i - 2] + 2;} // 情況 2: 子串形如 ".....))"// 且 s.charAt(i-1) 結尾的子串是有效的 (dp[i-1] > 0)// 我們需要檢查 s[i-1-dp[i-1]] 是否是與之匹配的'('else if (i - 1 - dp[i - 1] > 0 && s.charAt(i - 1 - dp[i - 1]) == '(') {// 長度 = s[i-1]結尾的子串長度 + 新匹配的"()"長度 + 更前面連接的有效子串長度dp[i] = dp[i - 1] + 2 + dp[i - 2 - dp[i-1]];}}// 每次計算完 dp[i]后,都用它來更新全局最大值 ans。ans = Math.max(ans, dp[i]);}return ans;}
}

時空復雜度

時間復雜度:O(N)

  1. 字符串拼接s = " " + s; 在Java中會創建一個新的字符串,這需要 O(N) 的時間。
  2. 循環:算法的核心是一個 for 循環,它從 i = 2 遍歷到 s.length() - 1。這個循環嚴格地執行 N-1 次(N 為原字符串長度)。
  3. 循環內部操作
    • 在循環的每一次迭代中,執行的都是常數次的操作:字符訪問 charAt()、數組訪問 dp[]、加減法和 Math.max
    • 這些操作的時間復雜度都是 O(1)

綜合分析
算法的總時間復雜度是 O(N) (字符串拼接) + O(N) (循環) = O(N)

空間復雜度:O(N)

  1. 主要存儲開銷
    • String s = " " + s;: 創建了一個新的字符串對象,其長度為 N+1,占用了 O(N) 的空間。
    • int[] dp = new int[s.length()]: 創建了一個 dp 數組,其長度也為 N+1,占用了 O(N) 的空間。

綜合分析
算法所需的額外空間主要由新的字符串對象和 dp 數組決定。因此,其空間復雜度為 O(N)

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

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

相關文章

使用Docker部署ZLMediaKit流媒體服務器實現gb/t28181協議的設備

最近在研究一個攝像頭&#xff0c;通信協議是 gb/t28181。對于這個協議也是第一次接觸&#xff0c;通過查閱多方資料&#xff0c;找到了兩個開源的源碼&#xff0c;來實現 視頻播放、攝像頭直播。以前也沒有深入的了解過關于視頻播放的這方面的技術&#xff0c;偶爾網站播放視頻…

硬件三人行--運算基礎篇

第3講 負反饋放大電路

【LINUX網絡】TCP原理

目錄 本文介紹 1. 什么是TCP&#xff1f; 2. TCP結構 為什么需要協議棧&#xff1a;兩臺主機通信的復雜性解決方案 3. 確認應答機制 進一步理解什么是確認和請求以及序號 進一步理解什么是序號和確認序號 并發發送帶來的問題以及解決方案&#xff08;序號&#xff09; …

Java -- 文件基礎知識--Java IO流原理--FileReader

目錄 1. 常用文件操作 2. Java IO流原理 2.1 流的分類 3. FileReader和FileWriter介紹 FileReader相關方法&#xff1a; FileWriter常用方法&#xff1a; 文件是保存數據的地方&#xff0c;比如大家經常使用的word文檔&#xff0c;txt文件&#xff0c;excel文件...都是文…

向量方法證明正余弦定理的數學理論體系

向量方法證明正余弦定理的數學理論體系 摘要&#xff1a; 向量理論為幾何定理的證明提供了強有力的代數化工具。本文基于向量空間的基本概念與運算性質&#xff0c;嚴格推導平面幾何中的正弦定理與余弦定理。通過建立系統的向量表示框架&#xff0c;將幾何關系轉化為向量運算&a…

【筆記ing】大模型算法架構

前言 隨著人工智能技術的飛速發展,大模型算法及其架構已成為推動科技前沿的重要力量。它們不僅能夠處理海量的數據,還具備強大的表征學習能力,能夠應對日益復雜的場景需求。本章節將介紹大模型算法及其架構,帶您了解其背后的原理、技術創新以及在實際應用中的廣闊前景。 …

ConcurrentHashMap的原理

1.底層數據結構JDK1.7底層采用分段的數組鏈表實現JDK1.8 采用的數據結構跟HashMap1.8的結構一樣,數組鏈表/紅黑二叉樹2.加鎖的方式JDK1.7采用Segment分段鎖,底層使用的是ReentrantLockJDK1.8采用CAS添加新節點,采用synchronized鎖定鏈表或紅黑二叉樹的首節點,相對Segment分段鎖…

【論文閱讀】健全個體無輔助運動期間可穿戴傳感器雙側下肢神經機械信號的基準數據集

Benchmark Datasets for Bilateral Lower-Limb Neuromechanical Signals from Wearable Sensors during Unassisted Locomotion in Able-Bodied Individuals 原文&#xff1a;DOI&#xff1a; 10.3389/frobt.2018.00014 2018年 翻譯&#xff1a;靠岸學術 目錄 1引言 2儀器設…

反向海淘系統搭建:從架構設計到合規運營的全方位指南

一、系統架構設計1.1 分層架構設計反向海淘系統通常采用四層架構設計&#xff1a;?接入層?&#xff1a;負責與淘寶開放平臺、1688海外接口通信&#xff0c;處理接口認證、請求轉發與響應解析。?業務層?&#xff1a;包含商品檢索、訂單管理、支付處理、物流追蹤等核心模塊。…

20.22 QLoRA微調實戰:中文語音識別數據準備全流程解密

QLoRA微調實戰:中文語音識別數據準備全流程解密 實戰項目:QLoRA 微調數據準備詳解 本環節我們將以中文語音識別任務為場景,詳細拆解 QLoRA 微調前的數據準備流程。以下流程圖展示了完整的數據處理路徑: #mermaid-svg-A3ZpWn1ysZUg6jg4 {font-family:"trebuchet ms&q…

工業電子看板賦能線纜工廠生產高效運轉

在制造業智能化轉型的浪潮中&#xff0c;工業電子看板已不再只是“顯示數據的屏幕”&#xff0c;而是成為連接設備層、控制層與管理層的實時信息樞紐。尤其在線纜制造這類對工藝參數敏感、生產連續性要求高的行業中&#xff0c;電子看板通過對關鍵數據的透明化、實時化與交互化…

Java爬蟲是什么,如何獲取API接口

一、Java爬蟲的定義Java爬蟲是一種基于Java編程語言開發的網絡爬蟲程序。它通過模擬瀏覽器行為&#xff0c;向目標網站發送HTTP請求&#xff0c;獲取網頁內容并解析出所需數據。Java爬蟲技術廣泛應用于數據采集、市場分析、競爭情報等領域。二、Java爬蟲獲取API接口的方法&…

Python篇---返回類型

基礎返回類型&#xff1a;在 Python 中&#xff0c;函數的返回類型就像函數 “產出” 的不同 “物品”&#xff0c;理解它們能幫你更好地控制代碼的輸出。下面用通俗的方式介紹常見的返回類型及用法&#xff1a;一、最基礎的返回類型1. 無返回值&#xff08;None&#xff09;特…

ArkTS 與 TypeScript 的關系及鴻蒙開發常見錯誤案例

隨著 HarmonyOS NEXT&#xff08;純血鴻蒙&#xff09; 的到來&#xff0c;開發者在學習鴻蒙應用開發時會遇到一個新的語言 —— ArkTS。很多人會疑惑&#xff1a;它和 TypeScript&#xff08;TS&#xff09;是什么關系&#xff1f;又有哪些新的特性&#xff1f;在實際開發中&a…

初識socket編程(實現一個簡單的TCPServer)

監聽套接字的創建流程 在網絡編程中&#xff0c;listen 套接字&#xff08;通常稱為“監聽套接字”&#xff09;是服務器端用于接收客戶端連接請求的特殊套接字&#xff0c;是 TCP 服務器建立連接過程中的核心組件。下面我們就來簡單看一下監聽套接字創建的過程創建流程&#x…

開發者如何在 Gitee 上開源一個自己的項目

文章目錄一、為什么要在 Gitee 上開源&#xff1f;1. 開源的價值2. 為什么是 Gitee&#xff1f;二、前期準備&#xff1a;讓項目“可開源”1. 項目代碼整理2. 添加必要文件3. 確定開源許可證三、在 Gitee 上創建倉庫四、推送本地代碼到 Gitee五、完善項目展示&#xff08;吸引力…

卷積神經網絡實現mnist手寫數字集識別案例

手寫數字識別是計算機視覺領域的“Hello World”&#xff0c;也是深度學習入門的經典案例。它通過訓練模型識別0-9的手寫數字圖像&#xff08;如MNIST數據集&#xff09;&#xff0c;幫助我們快速掌握神經網絡的核心流程。本文將以PyTorch框架為基礎&#xff0c;帶你從數據加載…

實戰筆記——構建智能Agent:SpreadJS代碼助手

目錄 前言 解決思路 需求理解 MCP Server LangGraph 本教程目標 技術棧 第一部分&#xff1a;構建 MCP Server - 工具服務化的基礎架構 第二部分&#xff1a;Tools 實現 第三部分&#xff1a;基于 LangGraph 構建智能 Agent 第四部分&#xff1a;服務器和前端搭建 前…

【Word】用 Python 輕松實現 Word 文檔對比并生成可視化 HTML 報告

在日常工作和學習中&#xff0c;我們經常需要對兩個版本的文檔進行比對&#xff0c;比如合同修改、論文修訂、報告更新等。手動逐字檢查不僅耗時費力&#xff0c;還容易遺漏細節。 今天&#xff0c;我將帶你使用 Python python-docx difflib 實現一個自動化 Word 文檔對比工具…

從0開始搭建一個前端項目(vue + vite + typescript)

版本 node&#xff1a;v22.17.1 pnpm&#xff1a;v10.13.1 vue&#xff1a;^3.5.18 vite&#xff1a;^7.0.6 typescipt&#xff1a;~5.8.0腳手架初始化vue pnpm create vuelatest只選擇&#xff1a; TypeScript, JSX 3. 用vscode打開創建的項目&#xff0c;并刪除多余的代碼esl…