算法(28)--矩陣搜索系列

矩陣搜索

  • 1.leetcode-200. 島嶼數量
  • 2.leetcode-695. 島嶼的最大面積
  • 3.leetcode-463. 島嶼的周長
  • 4.劍指 Offer 12. 矩陣中的路徑
  • 5.leetcode-329. 矩陣中的最長遞增路徑
  • 6.leetcode-1091. 二進制矩陣中的最短路徑

1.leetcode-200. 島嶼數量

給你一個由 ‘1’(陸地)和 ‘0’(水)組成的的二維網格,請你計算網格中島嶼的數量。

島嶼總是被水包圍,并且每座島嶼只能由水平方向或豎直方向上相鄰的陸地連接形成。

此外,你可以假設該網格的四條邊均被水包圍。

class Solution(object):def numIslands(self, grid):def dfs(r,c):grid[r][c]="0"for i,j in [(r+1,c),(r-1,c),(r,c+1),(r,c-1)]:if 0<=i<m and 0<=j<n and grid[i][j]=="1":# print(i,j)dfs(i,j)count=0m=len(grid)if m==0:return countn=len(grid[0])for r in range(m):for c in range(n):if  grid[r][c]=="1":count+=1dfs(r,c)return count

2.leetcode-695. 島嶼的最大面積

給定一個包含了一些 0 和 1 的非空二維數組 grid 。

一個 島嶼 是由一些相鄰的 1 (代表土地) 構成的組合,這里的「相鄰」要求兩個 1 必須在水平或者豎直方向上相鄰。你可以假設 grid 的四個邊緣都被 0(代表水)包圍著。

找到給定的二維數組中最大的島嶼面積。(如果沒有島嶼,則返回面積為 0 。)

class Solution(object):def __init__(self):self.count=0def maxAreaOfIsland(self, grid):def dfs(r,c):grid[r][c]=0 self.count+=1for i,j in [(r+1,c),(r-1,c),(r,c+1),(r,c-1)]:if 0<=i<m and 0<=j<n and grid[i][j]==1:dfs(i,j)res=0m=len(grid)if m==0:return resn=len(grid[0])for r in range(m):for c in range(n):if grid[r][c]==1:self.count=0dfs(r,c)res=max(res,self.count)return res

3.leetcode-463. 島嶼的周長

給定一個包含 0 和 1 的二維網格地圖,其中 1 表示陸地 0 表示水域。
網格中的格子水平和垂直方向相連(對角線方向不相連)。整個網格被水完全包圍,但其中恰好有一個島嶼(或者說,一個或多個表示陸地的格子相連組成的島嶼)。

島嶼中沒有“湖”(“湖” 指水域在島嶼內部且不和島嶼周圍的水相連)。格子是邊長為 1 的正方形。網格為長方形,且寬度和高度均不超過 100 。計算這個島嶼的周長。

在這里插入圖片描述
只有一個島嶼
從陸地走向邊界/水域,邊長+1。判斷下一個坐標是邊界位置還是水域,從而改變總周長。

class Solution(object):def __init__(self):self.res = 0def islandPerimeter(self, grid):def dfs(i,j):# print(i,j, self.res)grid[i][j] = 2for r, c in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:  # 走四個方向,看會發生什么情況嘛if r < 0 or r >= m or c < 0 or c >= n:     # 往邊界走了一格,# print("bian",i,j,r,c)self.res += 1if 0<= r < m and 0<= c < n and grid[r][c] == 0 : # 往水域走了一格# print("shui",i,j,r,c)self.res +=1if 0<= r < m and 0<= c < n and grid[r][c] == 1:   dfs(r,c)m = len(grid)if m == 0:return 0n = len(grid[0])for i in range(m):   # 要區別是走過的陸地不能走還是原本就是水域不能走for j in range(n):# print(i,j)if grid[i][j] == 1:dfs(i,j)return self.resgrid=[[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
so = Solution()
print(so.islandPerimeter(grid))

4.劍指 Offer 12. 矩陣中的路徑

請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那么該路徑不能再次進入該格子。例如,在下面的3×4的矩陣中包含一條字符串“bfce”的路徑(路徑中的字母用加粗標出)。

[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]

但矩陣中不包含字符串“abfb”的路徑,因為字符串的第一個字符b占據了矩陣中的第一行第二個格子之后,路徑不能再次進入這個格子。

約束:不能兩次經過同一個點
矩陣中的每一個元素,dfs + visted矩陣,上下左右匹配當前字符,
visted矩陣通過標記字符來實現

遞歸前保證矩陣下標的合理性,遞歸出口由匹配情況控制
1.word==""
2.len(word) == 1 and board[i][j] == word[0]
3.board[i][j] != word[0]
其他情況都是往下遞歸

class Solution(object):def exist(self, board, word):# board[i][j] 都進行深度優先匹配def dfs(i,j,word):if len(word) == 0:    # word 為空字符串時,匹配完成return Trueif len(word) == 1 and board[i][j] == word[0]:  # 防止[i][j]下一步都是邊界且是訪問過的情況,雖然已經匹配,但是結果是false,[["a"]]"a"return Trueif board[i][j] != word[0]: # 第一字符不匹配,完全不用遞歸,直接輸出return Falsetmp = board[i][j]                           # 完全沒有考慮不能重復走 board[i][j] = Nonefor r,c in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]: # 第一哥字符匹配,遞歸處理if 0<= r < m and 0 <= c < n:if dfs(r,c,word[1:]):  # 如果四個方向中有一格方向是可行的就返回True       return Trueboard[i][j] = tmpreturn False                # 第一個字符匹配了,但是后面的都不配,輸出Falsem = len(board)if m == 0:return word == "" n = len(board[0])for i in range(m):for j in range(n):if dfs(i,j,word):return Truereturn False  # 所有遍歷過了,沒有就輸出false#[["a"]],"a"
#[["a"]],"a"

5.leetcode-329. 矩陣中的最長遞增路徑

給定一個整數矩陣,找出最長遞增路徑的長度。
對于每個單元格,你可以往上,下,左,右四個方向移動。 你不能在對角線方向上移動或移動到邊界外(即不允許環繞)。

輸入: nums = 
[[9,9,4],[6,6,8],[2,1,1]
] 
輸出: 4 
解釋: 最長遞增路徑為 [1, 2, 6, 9]

keypoint:
1.遞增天然的不會兩次走過同一個單元
2.dp[i][j] 以matrix[i][j]開始的最長遞增路徑

class Solution(object):def longestIncreasingPath_cyy(self, matrix):def dfs(i,j):if dp[i][j]:return dp[i][j]for r, c in [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]:if 0<= r < m and 0 <= c < n  and matrix[r][c] > matrix[i][j]:dp[i][j] = max(dp[i][j], dfs(r,c))  # 下一層的最大深度dp[i][j] += 1  # 本層的深度在下層深度的基礎上+1return dp[i][j]m = len(matrix)if m == 0:return 0n = len(matrix[0])dp = [[0] * n for _ in range(m)]  # dp[i][j] 開始的最長路徑res = 0for i in range(m):for j in range(n):res = max(res,dfs(i,j))# print(dp)return res

6.leetcode-1091. 二進制矩陣中的最短路徑

在一個 N × N 的方形網格中,每個單元格有兩種狀態:空(0)或者阻塞(1)。

一條從左上角到右下角、長度為 k 的暢通路徑,由滿足下述條件的單元格 C_1, C_2, …, C_k 組成:

相鄰單元格 C_i 和 C_{i+1} 在八個方向之一上連通(此時,C_i 和 C_{i+1} 不同且共享邊或角)
C_1 位于 (0, 0)(即,值為 grid[0][0])
C_k 位于 (N-1, N-1)(即,值為 grid[N-1][N-1])
如果 C_i 位于 (r, c),則 grid[r][c] 為空(即,grid[r][c] == 0)
返回這條從左上角到右下角的最短暢通路徑的長度。如果不存在這樣的路徑,返回 -1 。

最短路徑問題:BFS

def shortestPathBinaryMatrix(self, grid):n = len(grid)if grid[0][0] == 1 or grid[-1][-1] == 1:return -1if n == 1:                # [[0]]這種特殊情況return 1res = 1que = [(0,0)]while(que):l = len(que)for i in range(l):(i,j) = que.pop(0)for (r,c) in [(i-1,j-1),(i-1,j),(i-1,j+1),(i,j-1),(i,j+1),(i+1,j-1),(i+1,j),(i+1,j+1)]:if 0<= r < n and 0<= c < n and grid[r][c] == 0: # 有效坐標 并且能走if r == n-1 and c == n-1:        # 能走到了終點return res + 1que.append((r,c))                # 能走沒到終點grid[r][c] = 1                   # 已經走過的地方不能再走,不然就會一直進隊出隊res += 1                                     # 廣度優先的層數return -1

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

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

相關文章

leetcode213 打家劫舍II

你是一個專業的小偷&#xff0c;計劃偷竊沿街的房屋&#xff0c;每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈&#xff0c;這意味著第一個房屋和最后一個房屋是緊挨著的。同時&#xff0c;相鄰的房屋裝有相互連通的防盜系統&#xff0c;如果兩間相鄰的房屋在同一晚…

linux下安裝boost

以下是在ubuntu 7.10 (內核 2.6.22-14)下安裝的例子&#xff1a; 一、下載最新的 boost 庫&#xff0c;下載地址&#xff1a; http://www.boost.org/users/download/ 二、在適當的位置解壓 boost 庫&#xff0c;推薦把 boost 庫解壓到 /usr/local/ 下&#xff1a; $ cd dowlo…

PaperNotes(4)-高質量圖像生成-CGAN-StackGAN-Lapgan-Cyclegan-Pix2pixgan

cgan,stackgan,lapgan,cyclegan,pix2pixgan1.Conditional GAN1.1簡介1.2網絡結構與訓練1.3特點與用途2.Stack GAN2.1簡介2.2網絡結構與訓練2.3特點與用途3.Lap GAN3.1簡介3.2網絡結構與訓練3.3特點與用途4.Pix2pix GAN4.1 簡介4.2 網絡結構和訓練4.3 特點和用途5.Patch GAN6.Cy…

關于c++的一些案例

之前做項目的時候,有時候會用到位,也就是將一些數據放在二進制里,然后存在數據庫中或者緩存在服務器上,取出來,然后要判斷某位是不是置0或1,然后再將某位置0或1(比如領多個獎勵的 游戲邏輯),之前有點傻,竟然用 << ,>>這些運算符計算,今天翻起以前好久不…

C++(1)--概況、開發工具、hello word

簡介1. 概況2. 開發工具3. mac 寫hello word4. c 基本概念5.兩個數相加代碼分解5.1編譯預處理命令# include5.2輸入輸出庫iostream6.注釋7.編碼規范《老九學堂C課程》《C primer》學習筆記。《老九學堂C課程》詳情請到B站搜索《老九零基礎學編程C入門》1. 概況 20世紀70年代&a…

class 和 struct的區別

C中的struct對C中的struct進行了擴充&#xff0c;它已經不再只是一個包含不同數據類型的數據結構了&#xff0c;它已經獲取了太多的功能。 struct能包含成員函數嗎&#xff1f; 能&#xff01; struct能繼承嗎&#xff1f; 能&#xff01;&#xff01; struct能實現多態嗎&…

leetcode206 反轉鏈表

反轉一個單鏈表。 示例: 輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL 進階: 你可以迭代或遞歸地反轉鏈表。你能否用兩種方法解決這道題&#xff1f; 經典題不解釋 /*** Definition for singly-linked list.* public class ListNode…

淺議柔性數組

很多時候,柔性數組應用在了變長結構體中,如: StructPacket {Int state; Int len;

leetcode 152 乘積最大子序列

給定一個整數數組 nums &#xff0c;找出一個序列中乘積最大的連續子序列&#xff08;該序列至少包含一個數&#xff09;。 示例 1: 輸入: [2,3,-2,4] 輸出: 6 解釋: 子數組 [2,3] 有最大乘積 6。 示例 2: 輸入: [-2,0,-1] 輸出: 0 解釋: 結果不能為 2, 因為 [-2,-1] 不是子…

PaperNotes(5)-Conditional Generative Adversarial Nets

Conditional GAN 論文閱讀筆記Abstract1 Introduction2 Related Work3 Conditional Adversarial Nets3.1 Generative Adversarial Nets3.2 Conditional Adversarial Nets4 Experimental Results4.1 Unimodal4.2 Multimodal5 Future Work6.思考文章地址&#xff1a;https://arxi…

蛙泳姿勢教學

偶爾看到分享的一篇日志&#xff0c;記錄下&#xff0c;忙過這段時間努力學蛙泳。 蛙泳配合有一個順口溜&#xff0c;在講解蛙泳動作要領之前先介紹給大家&#xff1a;“劃手腿不動&#xff0c;收手再收腿&#xff0c;先伸胳膊后蹬腿&#xff0c;并攏伸直漂一會兒。”從順口溜中…

leetcode238 除本身以外數組的乘積

給定長度為 n 的整數數組 nums&#xff0c;其中 n > 1&#xff0c;返回輸出數組 output &#xff0c;其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積。 示例: 輸入: [1,2,3,4] 輸出: [24,12,8,6] 說明: 請不要使用除法&#xff0c;且在 O(n) 時間復雜度內完…

C 和c++的一些雜想,想到哪兒寫到哪兒

關于C和c++一直有好多的程序猿在研究,研究區別研究相似的地方,究竟用那個預言好,沒有確定的說法,要看你做什么了。 初始化操作: 在初始化的時候,我們都知道C語言一般都是這樣處理的: int a=12; C++ 呢,除了這樣復制初始化之外還可以直接初始化: int a(12); 啊…

C++(2)--mac使用VScode 進行C++編譯、運行、調試

mac 使用VScode 進行C開發1.編譯的基礎概念2. mac 編譯c代碼2.1 查看編譯器情況2.2 安裝插件C/C&#xff0c;C/C Clang Command Adapte2.3新建一個C project2.3.1本地新建文件夾2.3.2新建mian.cpp文件2.3.3 編寫hello word demo2.4 代碼編譯&#xff0c;運行&#xff0c;調試2.…

boost庫linux編譯安裝

0.下載 1.解壓boost_1_49_0.tar.g然后放到/opt/ 2. 進入解壓后的文件夾 cd /opt/boost_1_49_0 3.將boost安裝配置在/boost/prefix目錄下 不過之前先 mkdir -p /boost/prefix

leetcode136 只出現一次的數字

給定一個非空整數數組&#xff0c;除了某個元素只出現一次以外&#xff0c;其余每個元素均出現兩次。找出那個只出現了一次的元素。 說明&#xff1a; 你的算法應該具有線性時間復雜度。 你可以不使用額外空間來實現嗎&#xff1f; 示例 1: 輸入: [2,2,1] 輸出: 1 示例 2: …

C++(3)--編譯、gdb調試

3--編譯和執行過程1.編譯2.gdb調試gdb 查coreGCC是一個編譯套件&#xff0c;是一個以"gcc"命令為首的源碼施工隊。施工隊的成員有gcc、cpp、as、ld四個成員 預處理–宏定義展開&#xff0c;頭文件引入-- cpp 等價于 gcc -E編譯–C語言->匯編語言–gcc -S匯編–匯…

leetcode94 二叉樹的中序遍歷

給定一個二叉樹&#xff0c;返回它的中序 遍歷。 示例: 輸入: [1,null,2,3] 1 \ 2 / 3 輸出: [1,3,2] 進階: 遞歸算法很簡單&#xff0c;你可以通過迭代算法完成嗎&#xff1f; 遞歸 /*** Definition for a binary tree node.* public class TreeNode …

使用動態鏈接庫

1. 動態鏈接庫是程序運行時加載的庫,當動態鏈接庫正確安裝后,所有的程序都可以使用動態庫來運行程序。動態鏈接庫是目標文件的集合,目標文件在動態鏈接庫中的組織方式是按照特殊方式形成的。庫中函數和變量的地址是相對地址,不是絕對地址,其真實地址在調用動態庫的程序加載…

算法(29)--兩棵樹匹配

樹匹配1.劍指 Offer 26. 樹的子結構2.劍指 Offer 27. 二叉樹的鏡像3.劍指 Offer 28. 對稱的二叉樹1.劍指 Offer 26. 樹的子結構 判斷&#xff1a;小樹B是否是大樹A的一部分&#xff0c;需要以大樹A的每個為根節點進行匹配判斷。 算法&#xff1a;判斷兩個節點是否相等&#xf…