leetcode 力扣刷題 旋轉矩陣(循環過程邊界控制)

力扣刷題 旋轉矩陣

  • 二維矩陣按圈遍歷(順時針 or 逆時針)遍歷
  • 59. 旋轉矩陣Ⅱ
  • 54. 旋轉矩陣
  • 劍指 Offer 29. 順時針打印矩陣

二維矩陣按圈遍歷(順時針 or 逆時針)遍歷

下面的題目的主要考察點都是,二維數組從左上角開始順時針(或者逆時針)按圈遍歷數組的過程。順時針按圈遍歷的過程如下:
在這里插入圖片描述

對于每一圈,分為四條邊,循環遍歷就好。這時,對于四個角的元素的處理,可以將四條邊的遍歷分為以下兩種情況:
在這里插入圖片描述

  • 第一種:每條邊都從對應一角開始,遍歷對應邊的時候,最后一個元素留給下一條邊;比如第一條綠色的邊,最后一個元素就沒有訪問;第二條黃色的邊就從左上角元素開始,相應的最左下角的元素沒有訪問;以此類推;
    代碼實現(C++):
        //count表示訪問了的元素個數,控制遍歷完數組沒有while(count <= n*n){//i,j是行、列的下標,每次總是從[0,0],[1,1]開始一圈循環int i = p;int j = p;//每圈最上面一條邊的遍歷         while(j < n - 1 - p){//因為最一個元素[i][n-1-p]留給下一條邊,因此這里不取等ans[i][j++] = count++;}//每圈最右邊的一條邊的遍歷while(i < n - 1 - p){//因為最一個元素[n-1-p][j]留給下一條邊,因此這里不取等ans[i++][j] = count++;}//每圈最下面一條邊的遍歷while(j > p){//因為最后一個元素[i][p]留給下一條邊,因此這里不取等ans[i][j--] = count++;}//每圈最左邊的一條邊的遍歷while(i > p){//因為[p][p]就是這一圈的起始點,在第一條邊就遍歷過了,所以這里取等ans[i--][j] = count++;}p++;}
  • 第二種:遍歷每一條邊時,就將該邊所有未被訪問的元素全部遍歷;比如第一條綠色的,最后一個元素就訪問了;然后第二條邊黃色的就對應列的第二個開始,因為第一個已經被訪問了;之后的邊以此類推;
    代碼實現(C++):
        //count控制遍歷完了沒有while(count <= n*n){   //遍歷最上邊的一條邊        for(int i = left; i <= right ; i++){ans[top][i] = count++;}//遍歷完后top++top++;//遍歷最右邊的邊for(int i = top; i <= bottom; i++){ans[i][right] = count++;}//遍歷完后right--right--;//遍歷最下邊的邊for(int i = right; i >= left ;i--){ans[bottom][i] = count++;}//遍歷完后bottom--bottom--;//遍歷最左邊一條邊for(int i = bottom; i >= top; i--){ans[i][left] = count++;}//遍歷完后left++left++;}

59. 旋轉矩陣Ⅱ

螺旋矩陣 II
題目內容如下:
在這里插入圖片描述
注意點是n*n的正方形矩陣,行列數量相同。只要按照前面提到的順時針訪問數組的過程中,給每個位置遞增賦值就好。按圈遍歷的過程中,需要循環遍歷多少次呢?答案是(n+1)/2次。
在這里插入圖片描述
但是按照上面提到的第一種俺圈遍歷的過程中:

  • n為偶數時,每次減少2行,2 列,最后剛好遍歷完;
  • n為奇數時,最后一次只有單獨一個,因為每條邊的最后一個元素都留給下一條邊了,所以實際上沒有哪條邊去遍歷了。比如n=5,p=2時,i=2,j=2,n-1-p=2,由于i=j=p=n-1-p,第一種代碼提到的四種循環條件都不滿足。所以在最后要單獨給這個位置賦值。代碼如下(C++):
class Solution {
public:vector<vector<int>> generateMatrix(int n) {int count = 1;int i, j, p;vector<vector<int>> ans(n,vector<int>(n));//因為n為奇數的最后一圈在最后單獨賦值,所以這里p<n/2就好for(int p = 0; p < n/2; p++){i = p;j = p;         while(j < n - 1 - p){ans[i][j++] = count++;}while(i < n - 1 - p){ans[i++][j] = count++;}while(j > p){ans[i][j--] = count++;}while(i > p){ans[i--][j] = count++;}}//n為奇數時,最后一個位置(最中間)單獨賦值if( n%2 != 0){ans[n/2][n/2] = count;}return ans;}
}; 

對于第二種按圈遍歷的過程,因為用top//bottom//left//right來控制,最后中間位置的能夠遍歷到,不需要額外的處理,代碼如下(C++):

class Solution {
public:vector<vector<int>> generateMatrix(int n) {        vector<vector<int>> ans(n,vector<int>(n));int left = 0, right = n - 1;int top = 0, bottom = n -1;int count = 1;while(count <= n*n){int i;for(i = left; i <= right ; i++){ans[top][i] = count++;}top++;for(i = top; i <= bottom; i++){ans[i][right] = count++;}right--;for(i = right; i >= left ;i--){ans[bottom][i] = count++;}bottom--;for(i = bottom; i >= top; i--){ans[i][left] = count++;}left++;}return ans;}
}; 

54. 旋轉矩陣

54. 旋轉矩陣
題意如下:在這里插入圖片描述
跟上一題不同的點在于,矩陣由nn變成了==mn==,m和n不一定相等,即現在的矩陣可能不再是正方形的了。那么根據m(行數)///n(偶數)是奇數還是偶數?大小關系可以分為以下七種情況:
在這里插入圖片描述
分析這7種情況,得出結論,只要滿足如下兩種情況之一,最后就有需要單獨處理的:

  • m<n并且m是奇數(不管n是奇是偶),最終會多出來一行(因為m行數更小,行先結束圈的遍歷,但是列還有更多的,所以多出來一行);
  • n<m并且n是奇數(不管m是奇是偶),最終會多出來一列(因為n列數更小,列先結束圈的遍歷,但是行還有很多,所以多出來一列);
    (m=n同為奇數的情況可以歸為上述任意一種)。
    代碼實現的過程,就是最終會判斷一下是否出現上面的情況,然后單獨處理這一行///這一列就好,代碼如下:
class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {int step_i = 0, step_j = 0, index = 0;int m = matrix.size(), n = matrix[0].size();vector<int> ans(m*n);//與上一題代碼基本一致,只是<m/2和<n/2需要單獨判斷while(step_i < m/2 && step_j < n/2){int i = step_i;int j = step_j;for(; j < n - 1 -step_j; j++){ans[index++] = matrix[i][j];}for(; i < m - 1 - step_i; i++){ans[index++] = matrix[i][j];}for(; j > step_j; j--){ans[index++] = matrix[i][j];}for(; i > step_i ;i--){ans[index++] = matrix[i][j];}step_i++;step_j++;}//行是奇數并且m<n,剩下一行if(m%2 != 0 && step_i == m/2){for(int j = step_j; j < n - step_j; j++)ans[index++] = matrix[step_i][j];}//列是奇數并且n<m,剩下一列else if(n%2 != 0 && step_j == n/2){for(int i = step_i; i < m -step_i; i++ )ans[index++] = matrix[i][step_j];} return ans;    }
};

如果用第二種按圈遍歷的方法,更簡單,只是在大循環內依次進行的四個小循環,需要在最后兩個循環添加額外的循環條件

class Solution {
public:vector<int> spiralOrder(vector<vector<int>>& matrix) {int m = matrix.size(), n = matrix[0].size();vector<int> ans(m*n);int left = 0, right = n - 1;int top = 0, bottom = m - 1;int index = 0;while(index < m*n){for(int i = left; i <= right; i++){ans[index++] = matrix[top][i];}top++;for(int i = top; i <= bottom; i++){ans[index++] = matrix[i][right];}right--;//需要添加額外的條件 index < m*n (根據實際題目要求選擇對應的約束條件for(int i = right; i >=left && index < m*n; i--){ans[index++] = matrix[bottom][i];}bottom--;//需要添加額外的條件index < m*n (根據實際題目要求選擇對應的約束條件for(int i = bottom; i >= top && index < m*n; i--){ans[index++] = matrix[i][left];}left++;}return ans;}
};

為什么要添加這兩個?請看下例:
在這里插入圖片描述

如果不在內層的四個循環的后兩個中添加額外的限制,就會出現多遍歷的情況。

劍指 Offer 29. 順時針打印矩陣

劍指 Offer 29. 順時針打印矩陣
和54是一樣的題目,只是注意m和n可能等于0。

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

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

相關文章

輸出無重復的3位數和計算無人機飛行坐標

編程題總結 題目一&#xff1a;輸出無重復的3位數 題目描述 從{1,2,3,4,5,6,7,8,9}中隨機挑選不重復的5個數字作為輸入數組‘selectedDigits’&#xff0c;能組成多少個互不相同且無重復數字的3位數?請編寫程》序&#xff0c;從小到大順序&#xff0c;以數組形式輸出這些3位…

C# Linq源碼分析之Take (一)

概要 在.Net 6 中引入的Take的另一個重載方法&#xff0c;一個基于Range的重載方法。因為該方法中涉及了很多新的概念&#xff0c;所以在分析源碼之前&#xff0c;先將這些概念搞清楚。 Take方法基本介紹 public static System.Collections.Generic.IEnumerable Take (this …

【LeetCode: 2811. 判斷是否能拆分數組】

&#x1f680; 算法題 &#x1f680; &#x1f332; 算法刷題專欄 | 面試必備算法 | 面試高頻算法 &#x1f340; &#x1f332; 越難的東西,越要努力堅持&#xff0c;因為它具有很高的價值&#xff0c;算法就是這樣? &#x1f332; 作者簡介&#xff1a;碩風和煒&#xff0c;…

NavMeshPlus 2D尋路插件

插件地址:h8man/NavMeshPlus&#xff1a; Unity NavMesh 2D Pathfinding (github.com) 我對Unity官方是深惡痛覺,一個2D尋路至今都沒想解決,這破引擎早點倒閉算了. 這插件是githun的開源項目,我本身是有寫jps尋路的,但是無法解決多個單位互相阻擋的問題(可以解決但是有性能問…

vue3+ts使用antv/x6 + 自定義節點

使用 2.x 版本 x6.antv 新官網: 安裝 npm install antv/x6 //"antv/x6": "^2.1.6",項目結構 1、初始化畫布 index.vue <template><div id"container"></div> </template><script setup langts> import { onM…

Python爬蟲——scrapy_基本使用

安裝scrapy pip install scrapy創建scrapy項目&#xff0c;需要在終端里創建 注意&#xff1a;項目的名字開頭不能是數字&#xff0c;也不能包含中文 scrapy startproject 項目名稱 示例&#xff1a; scrapy startproject scra_baidu_36創建好后的文件 3. 創建爬蟲文件&…

MySQL表的操作

文章目錄 MySQL表的操作1. 創建表2. 查看表2.1 查看數據庫中存在的表2.2 查看表的屬性2.3 查看創建時表的詳細信息 3. 修改表3.1 向表中添加記錄3.2 添加列3.3 修改列的數據類型3.4 刪除列3.5 表的重命名3.6 修改列名 4. 刪除表 MySQL表的操作 1. 創建表 CREATE TABLE table_…

博客系統【架構】

用戶管理 實現用戶的注冊、登錄、注銷等功能 使用Redis做緩存處理、阿里云短信服務 確保用戶身份驗證和安全性 使用Jwt來鑒權 userId (主鍵&#xff0c;自增長) username (唯一&#xff0c;用戶名)【用于普通登錄】email (唯一&#xff0c;用戶的電子郵件地址) password (存儲…

zabbix監控tomcat

一、zabbix監控Tomcat1.1 zbx-agent配置1.1.1 關閉防火墻&#xff0c;將安裝 Tomcat 所需軟件包傳到/opt目錄下1.1.2 安裝JDK1.1.3 設置JDK環境變量1.1.4 安裝啟動Tomcat1.1.5 配置 JMX 1.2 zbx-server配置1.2.1 安裝zabbix&#xff08;省略&#xff0c;可看上一篇博客&#xf…

Docker自動化部署安裝(十)之安裝SonarQube

這里選擇的是&#xff1a; sonarqube:9.1.0-community (推薦使用) postgres:9.6.23 數據庫(sonarqube7.9及以后便不再支持mysql&#xff0c;版本太低的話里面的一些插件會下載不成功的) 1、docker-sonarqube.yml文件 version: 3 services:sonarqube:container_name: sonar…

Redis詳解

Redis 簡介 Redis&#xff08;Remote Dictionary Server&#xff09;是一個開源的高性能鍵值對存儲數據庫&#xff0c;最初由 Salvatore Sanfilippo 開發&#xff0c;它在內存中存儲數據&#xff0c;并提供了持久化功能&#xff0c;可以將數據保存到磁盤中&#xff0c;是一種N…

? vue中$forceUpdate()

? vue中$forceUpdate() 1、認識 強制該組件重新渲染 鑒于 Vue 的全自動響應性系統&#xff0c;這個功能應該很少會被用到 $forceUpdate()迫使vue實例重新&#xff08;rander&#xff09;渲染虛擬DOM&#xff0c;注意并不是重新加載組件。 結合vue的生命周期&#xff0c;調用…

【論文閱讀】DEPCOMM:用于攻擊調查的系統審核日志的圖摘要(SP-2022)

Xu Z, Fang P, Liu C, et al. Depcomm: Graph summarization on system audit logs for attack investigation[C]//2022 IEEE Symposium on Security and Privacy (SP). IEEE, 2022: 540-557. 1 摘要 ? 提出了 DEPCOMM&#xff0c;這是一種圖摘要方法&#xff0c;通過將大圖劃…

簡單易懂的python生成器

目錄 定義使用 for 循環來迭代生成器對象斐波那契 定義 在 Python 中&#xff0c;使用了 yield 的函數被稱為生成器&#xff08;generator&#xff09;。Python 中的生成器&#xff08;Generator&#xff09;是一種特殊的迭代器&#xff0c;可以通過函數來創建。與常規函數不同…

Feign忽略Https的SSL最佳方案(且保證負載均衡將失效)

同時解決Https的SSL證書驗證問題和feign不支持Patch請求方法的問題 代碼 1. 工具類 OkHttpUtils.java import javax.net.ssl.*; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import j…

從0開始搭建ns3環境以及NetAnim簡單使用

一、環境準備 ns3是基于GNU/Linux平臺使用C開發的工具軟件&#xff0c;在windows系統中安裝使用ns3環境&#xff0c;可以使用虛擬機VMware并安裝ubuntu系統來實現&#xff0c;現將本教程所用到的虛擬機和系統鏡像放到網盤提供下載 名稱鏈接提取碼VMware Workstation 17 Proht…

簡約時尚的健康手表,智能守護每一刻,dido Y60上手

智能手表是現在很流行的一種智能設備&#xff0c;很多品牌都推出了各種各樣的產品&#xff0c;但是大部分都更側重功能和運動的方面&#xff0c;健康監測往往只是配角&#xff0c;而隨著人們對自己的健康越來越重視&#xff0c;有些朋友只是單純的需要一塊專業的健康監測手表。…

選擇任務管理軟件:哪個更適合你的需求?

隨著互聯網的發展&#xff0c;知識管理是可以成為企業獲得更大發展前景的神兵利器&#xff0c;任務協同&#xff0c;是服務于中小型團隊&#xff0c;或者大型機構的終端組織。來看看這款國外流行的任務管理軟件Zoho Projects。 任務管理是企業協同的重要組成部分。 任務管理是企…

Bitcoin 加速交易操作示例

這里以 Bitcoin Ordinals NFT 為例&#xff0c; 進行加速交易演示 第1步&#xff1a;新建子賬戶 溫馨提示&#xff1a;如果有多條魚未確認&#xff0c;也只需1個賬戶即可&#xff0c;不必搞多個子賬戶 第2步&#xff1a;切換回到老地址&#xff08;Account 1&#xff09; 第3步…

【Kubernetes】Kubernetes的PV和PVC的用法

PV、PVC 前言一、 存儲卷1. emptyDir 存儲卷1.1 概念1.2 實例 2. hostPath 存儲卷2.1 概念2.2 實例 3. nfs共享存儲卷 二、PV 和 PVC1. 概念1.1 PV1.2 PVC1.3 PVC 的使用邏輯1.4 創建機制1.5 PV 和 PVC 的生命力周期1.6 創建及銷毀 PV 的流程 2. PV 和 PVC 的創建2.1 查看定義2…