力扣top100(day03-02)--圖論

?本文為力扣TOP100刷題筆記

筆者根據數據結構理論加上最近刷題整理了一套 數據結構理論加常用方法以下為該文章:

力扣外傳之數據結構(一篇文章搞定數據結構)

200. 島嶼數量

class Solution {// DFS輔助方法,用于標記和"淹沒"島嶼void dfs(char[][] grid, int r, int c) {int nr = grid.length;    // 網格行數int nc = grid[0].length; // 網格列數// 邊界檢查及是否陸地的檢查if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {return;}// 將當前陸地標記為已訪問('0'表示水或已訪問)grid[r][c] = '0';// 向四個方向遞歸搜索dfs(grid, r - 1, c); // 上dfs(grid, r + 1, c); // 下dfs(grid, r, c - 1); // 左dfs(grid, r, c + 1); // 右}public int numIslands(char[][] grid) {// 處理空網格的情況if (grid == null || grid.length == 0) {return 0;}int nr = grid.length;    // 網格行數int nc = grid[0].length; // 網格列數int num_islands = 0;     // 島嶼計數器// 遍歷整個網格for (int r = 0; r < nr; ++r) {for (int c = 0; c < nc; ++c) {// 發現新島嶼if (grid[r][c] == '1') {++num_islands;    // 增加島嶼計數dfs(grid, r, c);  // "淹沒"整個島嶼}}}return num_islands;}
}

關鍵點解釋

  1. DFS標記過程

    • 將訪問到的'1'標記為'0',避免重復計數

    • 向四個方向(上、下、左、右)遞歸搜索相連的陸地

  2. 島嶼計數邏輯

    • 每次遇到未被訪問的'1',表示發現新島嶼

    • 調用DFS"淹沒"整個島嶼,確保不會重復計數

  3. 邊界條件處理

    • 檢查網格坐標是否越界

    • 處理空網格輸入的情況

示例演示

給定網格:

text

1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

執行過程:

  1. 發現(0,0)的'1',計數+1,DFS淹沒左上角2×2島嶼

  2. 跳過已訪問/水區域

  3. 發現(2,2)的'1',計數+1,DFS淹沒該孤立點

  4. 發現(3,3)的'1',計數+1,DFS淹沒右下角2×1島嶼

  5. 最終島嶼數量:3

994. 腐爛的橘子

class Solution {public int orangesRotting(int[][] grid) {if (grid == null || grid.length == 0) return -1;int rows = grid.length;int cols = grid[0].length;int minutes = 0;while (true) {boolean changed = false;int[][] newGrid = new int[rows][cols];// 復制當前網格狀態for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {newGrid[i][j] = grid[i][j];}}// 遞歸處理每個橘子for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {if (grid[i][j] == 2) {changed |= infectAdjacent(grid, newGrid, i, j, rows, cols);}}}// 如果沒有變化,退出循環if (!changed) break;// 更新網格并增加分鐘數grid = newGrid;minutes++;}// 檢查是否還有新鮮橘子for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {if (grid[i][j] == 1) return -1;}}return minutes;}// 遞歸感染相鄰橘子的輔助方法private boolean infectAdjacent(int[][] grid, int[][] newGrid, int i, int j, int rows, int cols) {boolean changed = false;int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};for (int[] dir : directions) {int x = i + dir[0];int y = j + dir[1];if (x >= 0 && y >= 0 && x < rows && y < cols && grid[x][y] == 1) {newGrid[x][y] = 2;changed = true;}}return changed;}
}

遞歸思路解析

  1. 外層循環:每分鐘處理一次腐爛過程

  2. 網格復制:創建新網格來記錄下一分鐘的狀態

  3. 遞歸處理

    • 遍歷每個腐爛橘子(值為2)

    • 使用infectAdjacent方法遞歸感染相鄰的新鮮橘子

  4. 終止條件

    • 當沒有更多橘子可以被感染時退出循環

    • 最后檢查是否還有剩余的新鮮橘子

為什么這不是純遞歸

實際上,這個問題不太適合純遞歸解決,因為:

  1. 多源點問題:多個腐爛橘子需要同時擴散

  2. 時間步長:需要按分鐘同步處理所有腐爛

上面的解決方案使用了遞歸輔助方法,但整體結構仍然是迭代的(每分鐘處理一次)。

純遞歸的局限性

如果非要實現純遞歸版本,會遇到以下問題:

  1. 難以同步時間:所有腐爛過程無法同步進行

  2. 重復計算:同一個橘子可能被多次處理

  3. 棧溢出風險:對于大網格會超出調用棧深度

207. 課程表

class Solution {// 鄰接表,存儲圖的邊關系,edges.get(i)表示課程i的所有后續課程List<List<Integer>> edges;// 記錄每個節點的訪問狀態:0=未訪問,1=訪問中,2=已訪問完成int[] visited;// 全局標志,表示當前是否沒有發現環(能否完成所有課程)boolean valid = true;public boolean canFinish(int numCourses, int[][] prerequisites) {// 初始化鄰接表edges = new ArrayList<List<Integer>>();for (int i = 0; i < numCourses; ++i) {edges.add(new ArrayList<Integer>());}// 初始化訪問狀態數組visited = new int[numCourses];// 構建圖的邊關系// prerequisites中的每個元素[1,0]表示要學習課程1必須先完成課程0// 所以在鄰接表中,我們添加邊 0→1for (int[] info : prerequisites) {edges.get(info[1]).add(info[0]);}// 對每個未訪問的節點執行DFSfor (int i = 0; i < numCourses && valid; ++i) {if (visited[i] == 0) {dfs(i);}}// 如果整個過程中沒有發現環,則可以完成所有課程return valid;}public void dfs(int u) {// 標記當前節點為"訪問中"visited[u] = 1;// 遍歷當前節點的所有鄰接節點(后續課程)for (int v: edges.get(u)) {// 如果鄰接節點未被訪問,遞歸訪問if (visited[v] == 0) {dfs(v);// 如果在遞歸過程中發現環,提前返回if (!valid) {return;}} // 如果鄰接節點正在訪問中(在遞歸棧中),說明發現環else if (visited[v] == 1) {valid = false;return;}// 如果鄰接節點已訪問完成(2),不需要處理}// 當前節點訪問完成,標記為"已訪問"visited[u] = 2;}
}

關鍵注釋說明

  1. 鄰接表edges

    • 使用ArrayList的ArrayList實現

    • edges.get(i)獲取課程i的所有直接后續課程列表

  2. visited數組三種狀態

    • 0:白色,未訪問節點

    • 1:灰色,正在訪問中的節點(在遞歸棧中)

    • 2:黑色,已完全訪問完成的節點

  3. 環檢測邏輯

    • 在DFS過程中,如果遇到灰色節點(狀態1),說明存在環

    • 因為灰色節點表示該節點在當前的遞歸調用棧中,再次遇到說明形成了環

  4. DFS過程

    • 先將節點標記為灰色(訪問中)

    • 遞歸訪問所有鄰接節點

    • 最后將節點標記為黑色(訪問完成)

  5. 提前終止

    • 一旦發現環(valid=false),立即終止后續的DFS過程

這個算法有效地利用DFS實現了有向無環圖(DAG)的檢測,解決了課程安排問題。

208. 實現 Trie (前綴樹)

class Trie {// 每個Trie節點包含:// 1. 一個長度為26的子節點數組(對應26個小寫字母)// 2. 一個布爾值標記是否是某個單詞的結尾private Trie[] children;private boolean isEnd;// 構造函數:初始化一個空的Trie節點public Trie() {children = new Trie[26];  // 26個字母的子節點isEnd = false;           // 初始時不是單詞結尾}// 向Trie中插入一個單詞public void insert(String word) {Trie node = this;  // 從根節點開始for (int i = 0; i < word.length(); i++) {char ch = word.charAt(i);int index = ch - 'a';  // 計算字母對應的索引(0-25)// 如果當前字符對應的子節點不存在,則創建新的子節點if (node.children[index] == null) {node.children[index] = new Trie();}// 移動到子節點node = node.children[index];}// 標記單詞的最后一個字符節點為結尾node.isEnd = true;}// 搜索Trie中是否存在完整的單詞public boolean search(String word) {Trie node = searchPrefix(word);// 不僅要找到前綴,最后一個節點還必須標記為單詞結尾return node != null && node.isEnd;}// 檢查Trie中是否有以給定前綴開頭的單詞public boolean startsWith(String prefix) {// 只需要找到前綴路徑存在即可return searchPrefix(prefix) != null;}// 私有輔助方法:搜索前綴private Trie searchPrefix(String prefix) {Trie node = this;  // 從根節點開始for (int i = 0; i < prefix.length(); i++) {char ch = prefix.charAt(i);int index = ch - 'a';  // 計算字母對應的索引(0-25)// 如果當前字符對應的子節點不存在,返回nullif (node.children[index] == null) {return null;}// 移動到子節點node = node.children[index];}// 返回前綴的最后一個字符節點return node;}
}

關鍵注釋說明

  1. 數據結構設計

    • children數組:每個元素對應一個字母(a-z),存儲指向子Trie節點的引用

    • isEnd標志:標記當前節點是否是某個單詞的結尾

  2. 插入操作(insert)

    • 從根節點開始,逐個字符處理

    • 對于每個字符,檢查對應的子節點是否存在,不存在則創建

    • 最后將單詞的最后一個字符節點標記為結尾

  3. 搜索操作(search)

    • 使用searchPrefix方法找到前綴的最后一個節點

    • 檢查該節點是否存在且被標記為單詞結尾

  4. 前綴檢查(startsWith)

    • 只需要檢查前綴路徑是否存在,不關心是否是完整單詞

  5. 輔助方法(searchPrefix)

    • 通用的前綴查找方法

    • 被search和startsWith方法復用

    • 返回前綴路徑的最后一個節點(如果存在)

時間復雜度分析

  • 插入:O(L),L為單詞長度

  • 搜索:O(L),L為單詞長度

  • 前綴檢查:O(P),P為前綴長度

空間復雜度

  • 最壞情況:O(N×M),N是單詞數量,M是平均單詞長度

  • 實際中由于共享前綴,空間效率通常比哈希表更好

這個Trie實現特別適合處理字符串的前綴相關問題,如自動補全、拼寫檢查等場景。

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

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

相關文章

建造者模式:從“參數地獄”到優雅構建

深夜&#xff0c;一條緊急告警刺穿寂靜&#xff1a;核心報表服務因NullPointerException全線崩潰。排查根源&#xff0c;罪魁禍首竟是一個擁有10多個參數的“上帝構造函數”。本文將從這個災難現場出發&#xff0c;引入“鏈式建造者模式”進行重構&#xff0c;并深入Spring AI、…

jenkins在windows配置sshpass

我的服務器里jenkins是通過docker安裝的&#xff0c;jenkins與項目都部署在同一臺服務器上還好&#xff0c;但是當需要通過jenkins構建&#xff0c;再通過scp遠程推送到別的服務器上&#xff0c;就出問題了&#xff0c;畢竟不是手動執行scp命令&#xff0c;可以手動輸入密碼&am…

Linux操作系統從入門到實戰(十八)在Linux里面怎么查看進程

Linux操作系統從入門到實戰&#xff08;十八&#xff09;在Linux里面怎么查看進程前言一、如何識別一個進程&#xff1f;—— PID二、怎么查看進程的信息&#xff1f;方式1&#xff1a;通過/proc目錄方式2&#xff1a;用ps命令三、父進程是什么&#xff1f;—— PPID四、bash是…

[TryHackMe](知識學習)---基于堆棧得到緩沖區溢出

1.了解緩沖區溢出WINDOWS程序動態調試工具immunity debuggerhttps://www.immunityinc.com/products/debugger/2.Mona腳本#!/usr/bin/env python3import socket, time, sysip "10.201.99.37"port 1337 timeout 5 prefix "OVERFLOW1 "string prefix &q…

LRU算法與LFU算法

知識點&#xff1a; LRU是Least Recently Used的縮寫&#xff0c;意思是最近最少使用&#xff0c;它是一種Cache替換算法 Cache的容量有限&#xff0c;因此當Cache的容量用完后&#xff0c;而又有新的內容需要添加進來時&#xff0c; 就需要挑選 并舍棄原有的部分內容&#xf…

目標檢測公開數據集全解析:從經典到前沿

目標檢測公開數據集全解析&#xff1a;從經典到前沿 一、引言 目標檢測&#xff08;Object Detection&#xff09;是計算機視覺領域的核心任務之一&#xff0c;旨在在圖像或視頻中識別并定位感興趣的物體。與圖像分類不同&#xff0c;目標檢測不僅需要判斷物體的類別&#xf…

數據備份與進程管理

一、數據備份1.Linux服務器中需要備份的數據&#xff08;1&#xff09;Linux系統重要數據&#xff1a;/root/目錄&#xff0c;/home/目錄&#xff0c;/etc/目錄&#xff08;2&#xff09;安裝服務的數據&#xff1a;Apache&#xff08;配置文件&#xff0c;網頁主目錄&#xff…

docker volume卷入門教程

1. 基礎概念 Docker卷是專門用于持久化容器數據的存儲方案&#xff0c;獨立于容器生命周期。其核心優勢包括&#xff1a; 數據持久化&#xff1a;容器刪除后數據仍保留跨容器共享&#xff1a;多個容器可訪問同一卷備份與遷移&#xff1a;支持直接復制卷數據驅動支持&#xff1a…

計算機網絡——協議

1. 計算機網絡分層1.1 OSI 7層模型應用層表示層會話層傳輸層網絡層數據鏈路層物理層1.2 TCP/IP 4 層模型應用層運輸層網際層網絡接口層1.3 5層體系機構應用層傳輸層網絡層數據鏈路層物理層2. 應用層協議2.1 HTTP協議2.1.1 基本介紹HTTP&#xff08;HyperText Transfer Protocol…

【React】hooks 中的閉包陷阱

在 React Hooks 中的 閉包陷阱&#xff08;Closure Trap&#xff09;在 useEffect、事件回調、定時器等場景里很常見。1. 閉包陷阱是什么 當你在函數組件里定義一個回調&#xff08;比如事件處理函數&#xff09;&#xff0c;這個回調會捕獲當時渲染時的變量值。如果后面狀態更…

校園快遞小程序(騰訊地圖API、二維碼識別、Echarts圖形化分析)

&#x1f388;系統亮點&#xff1a;騰訊地圖API、二維碼識別、Echarts圖形化分析&#xff1b;一.系統開發工具與環境搭建1.系統設計開發工具后端使用Java編程語言的Spring boot框架 項目架構&#xff1a;B/S架構 運行環境&#xff1a;win10/win11、jdk17小程序&#xff1a; 技術…

Python網絡爬蟲(二) - 解析靜態網頁

文章目錄一、網頁解析技術介紹二、Beautiful Soup庫1. Beautiful Soup庫介紹2. Beautiful Soup庫幾種解析器比較3. 安裝Beautiful Soup庫3.1 安裝 Beautiful Soup 43.2 安裝解析器4. Beautiful Soup使用步驟4.1 創建Beautiful Soup對象4.2 獲取標簽4.2.1 通過標簽名獲取4.2.2 通…

【Linux基礎知識系列】第九十四篇 - 如何使用traceroute命令追蹤路由

在網絡環境中&#xff0c;了解數據包從源主機到目標主機的路徑是非常重要的。這不僅可以幫助我們分析網絡連接問題&#xff0c;還可以用于診斷網絡延遲、丟包等問題。traceroute命令是一個強大的工具&#xff0c;它能夠追蹤數據包在網絡中的路徑&#xff0c;顯示每一跳的延遲和…

達夢數據閃回查詢-快速恢復表

Time:2025/08/12Author:skatexg一、環境說明DM數據庫&#xff1a;DM8.0及以上版本二、適用場景研發在誤操作或變更數據后&#xff0c;想馬上恢復表到某個時間點&#xff0c;可以通過閃回查詢功能快速實現&#xff08;通過全量備份恢復時間長&#xff0c;成本高&#xff09;三、…

力扣(LeetCode) ——225 用隊列實現棧(C語言)

題目&#xff1a;用隊列實現棧示例1&#xff1a; 輸入&#xff1a; [“MyStack”, “push”, “push”, “top”, “pop”, “empty”] [[], [1], [2], [], [], []] 輸出&#xff1a; [null, null, null, 2, 2, false] 解釋&#xff1a; MyStack myStack new MyStack(); mySta…

微軟推出AI惡意軟件檢測智能體 Project Ire

開篇 在8月5號&#xff0c;微軟研究院發布了一篇博客文章&#xff0c;在該篇博客中推出了一款名為Project Ire的AI Agent。該Agent可以在無需人類協助的情況下&#xff0c;自主分析和分類二進制文件。它可以在無需了解二進制文件來源或用途的情況下&#xff0c;對文件進行完全的…

哪些對會交由SpringBoot容器管理?

在 Spring Boot 中,交由容器管理的對象通常稱為“Spring Bean”,這些對象的創建、依賴注入、生命周期等由 Spring 容器統一管控。以下是常見的會被 Spring Boot 容器管理的對象類型及識別方式: 一、通過注解聲明的組件(最常見) Spring Boot 通過類級別的注解自動掃描并注…

Android POS應用在android運行常見問題及解決方案

概述 本文檔記錄了在Android POS應用開發過程中遇到的兩個關鍵問題及其解決方案&#xff1a; UnsatisfiedLinkError: couldnt find "libnative.so" 錯誤ActivityNotFoundException 錯誤商戶信息一致性檢查繞過 問題1&#xff1a;UnsatisfiedLinkError - libnative.so…

基于SpringBoot的旅游網站系統

1. 項目簡介 旅游線路管理系統是一個基于Spring Boot的在線旅游服務平臺&#xff0c;提供旅游線路展示、分類、預訂、訂單管理等功能。系統包含前臺用戶界面和后臺管理模塊&#xff0c;支持用戶注冊登錄、線路瀏覽、收藏、下單支付、客服咨詢等核心功能。管理員可管理線路信息、…

CVPR 2025 | 機器人操控 | RoboGround:用“掩碼”中介表示,讓機器人跨場景泛化更聰明

點擊關注gongzhonghao【計算機sci論文精選】1.導讀1.1論文基本信息論文標題&#xff1a;ROBOGROUND: Robotic Manipulation with Grounded Vision-Language Priors作者&#xff1a;Haifeng Huang, Xinyi Chen, Hao Li&#xff0c; Xiaoshen Han, Yilun Chen, Tai Wang, Zehan W…