論螺旋矩陣

螺旋矩陣題型總結。我刷了幾道螺旋矩陣相關的題目,這里我們介紹一下一些常見的解法。

螺旋矩陣

方形矩陣

當我們遇到n*n的方形矩陣時,可以用一種特殊的解法來遍歷實現,以下面這道題為例:

59. 螺旋矩陣 II

我們可以定義幾個變量用來控制遍歷的行為:

  • startX:每次循環的起點的行數

  • startY:每次循環的起點的列數

  • offset:每循環一圈,用偏移量表現

vector<vector<int>> generateMatrix(int n) {vector<vector<int>> ans(n,vector<int>(n,0));int offset = 1 , startX = 0 , startY = 0;int val = 1;int i,j;for(int k=0;k<n/2;k++){     //循環次數就是圈數for(j=startY;j<n-offset;j++)    //左上->右上(從此以下都是左閉右開)ans[startX][j] = val++;for(i=startX;i<n-offset;i++)    //右上->右下ans[i][j] = val++;for(;j>startY;j--)              //右下->左下    ans[i][j] = val++;for(;i>startX;i--)              //左下->右上ans[i][j] = val++;startX++;startY++;offset++;   //實際上更新offset就是在更新每次循環的邊界(縮小)}if (n&1){   //如果矩陣的邊長為奇數,最中間的值會沒法遍歷到ans[offset-1][offset-1] = val;}return ans;}
};

同時還可以將方形矩陣視作一種特殊的矩形矩陣,以下對矩形矩陣的所有解法對方形都適用。

矩形矩陣

有時候我們會發現矩陣是矩形的,或者只有一層,這個時候就需要用幾個通用的方法,來實現。例題:

LCR 146. 螺旋遍歷二維數組

54. 螺旋矩陣

2326. 螺旋矩陣 IV

模擬路徑法

我們先分析我們的轉向條件:(1)當前進的方向上碰到了邊界(2)當前進的方向上是已經走過的路徑

第一個條件比較好解決,第二條件我們需要維護一個和數組相同大小的矩陣,走過的路線我們設置為true,沒走過的設置為false.

由于我們的轉向動作是有序的,是順時針,所以我們可以使用一個數組來存儲我們的方向。當到達轉向條件時,設置成下一個轉向動作。

vector<int> spiralArray(vector<vector<int>>& array) {if(array.empty()||array[0].empty()) //判斷數組是否為空,注意先后順序,array[0]在array為空時是不能訪問的return {};int row = array.size();int col = array[0].size();int total = row*col;vector<vector<bool>> use(row,vector<bool>(col,0));  //路徑表vector<int> ans(total,0);vector<vector<int>> direction{{0,1},{1,0},{0,-1},{-1,0}};   //方向表(順時針)int directionIdx = 0;   //方向表索引int i=0,j=0;for(int k=0;k<total;k++){ans[k] = array[i][j];use[i][j] = true;int ni = i + direction[directionIdx][0];    //預更新iint nj = j + direction[directionIdx][1];    //預更新jif(ni<0||ni>=row||nj<0||nj>=col||use[ni][nj]==true){    //根據預更新狀態判斷轉向條件directionIdx = (directionIdx+1)%4;  //轉向則把方向索引設置到下一位}//實際更新i = i + direction[directionIdx][0];j = j + direction[directionIdx][1];}return ans;}

層級遍歷法(邊界收縮)

這個和剛剛用來解決方形矩陣的方法是相同的,只不過更新方式和更新條件要更加復雜。

一開始先設定好邊界,當移動到邊界的時候就轉向,然后收縮邊界。這樣的好處在于我們不用再特意維護一個數組來判斷路徑是否被走過 了。因為走過的路徑被我們收縮了,所以就不用在考慮。只需要在邊界做檢測就好了。

vector<vector<int>> spiralMatrix(int m, int n, ListNode* head) {vector<vector<int>> ans(m,vector<int>(n,-1));int top = 0;    int bottom = m-1;   //-1是因為索引和實際位置的差值int left = 0;int right = n-1;while(left<=right&&top<=bottom){    //如果相等就說明,邊界收縮了,遍歷結束了for(int i=left;i<=right;i++)    ans[top][i] = val;top++;                          //左上->右上 top邊界收縮for(int i=top;i<=bottom;i++)ans[i][right] = val;right--;                        //右上->右下 right邊界收縮for(int i=right;i>=left;i--)ans[bottom][i] = val;bottom--;                       //右下->左下 bottom邊界收縮for(int i=bottom;i>=top;i--)ans[i][left] = val;left++;                         //左下->右上 left邊界收縮}return ans;}

螺旋生成矩陣

這個算是一個小特例,大多數題目是給你一個矩陣讓你去螺旋遍歷,但是有的題目需要你自己螺旋生成一個矩陣。我們看到下面的例題:

885. 螺旋矩陣 III

image.png

這道題需要我們形成一個螺旋的路徑,然后返回矩形內的位置的坐標。難點在于這個螺旋路徑的生成,因為轉向的條件和每次前進的步長綜合考慮起來條件會非常的復雜。下面的話給出兩種方法。

邊界擴展法

和我們之前所做的邊界收縮相反,我們先界定好邊界,然后每次轉向時寬展這個方向上的邊界。通過這種方式來動態的生成一個螺旋的路徑

const int DIR[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
vector<vector<int>> spiralMatrixIII(int rows, int cols, int rStart, int cStart) {vector<vector<int>> ans;int total = rows*cols;int num = 1;int i = rStart,j = cStart;  //令i,j記錄路徑的實時位置int left = cStart - 1,right = cStart + 1,top = rStart - 1,bottom = rStart + 1;  //確定邊界int dir=0;  //記錄方向while(num <= total){if(i>=0&&i<rows&&j>=0&&j<cols){ //當路徑到達矩陣內部時,記錄當前位置ans.push_back({i,j});num++;}if(dir==0&&j==right){   //如果向右移動觸碰右邊界dir+=1;             //則轉向right++;            //并拓展右邊界}else if(dir==1&&i==bottom){    //如果向下移動觸碰下邊界dir+=1;                     //則轉向bottom++;                   //并拓展下邊界}else if(dir==2&&j==left){      //...dir+=1;left--;}else if(dir==3&&i==top){       //...dir=0;top--;}i += DIR[dir][0];       //根據方向來更新位置j += DIR[dir][1];}return ans;}

規律法

我們可以觀察螺線路徑的一個顯著規律:每轉向兩次會更新一次前進的步長

const int DIR[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
vector<vector<int>> spiralMatrixIII(int R, int C, int r0, int c0) {int num=0;int dir=0;int run=2;  //步長計數器vector<vector<int>> ans;
?while(num < R * C){for(int i = 0; i < run / 2; i ++){ ? //遍歷步長,每轉兩下就會增加一步if(r0 >= 0 && r0 < R && c0 >= 0 && c0 < C)ans.push_back({r0, c0}), ++ num;r0 += DIR[dir][0];c0 += DIR[dir][1];}pos = (pos + 1) % 4;    //每遍歷一次步長,就轉向run++;      //利用取整的性質,每轉向兩次才會增加一次步長}return ans;}

總結

螺旋矩陣的關鍵在于邊界的檢測和變換,還有轉向條件的判斷。比較簡單。

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

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

相關文章

數學金融與金融工程:學科差異與選擇指南

在金融領域的學習中&#xff0c;數學金融與金融工程常被混淆。兩者雖同屬 “金融 量化” 交叉方向&#xff0c;但在研究側重、培養路徑上有顯著區別。結合學科特點與行業實踐&#xff0c;幫大家理清兩者的核心差異&#xff0c;以便更精準地選擇方向。一、核心差異&#xff1a;…

包管理工具npm cnpm yarn的使用

包管理工具 1. 什么是包管理工具? 包管理工具是用于管理和安裝 Node.js 項目依賴的工具。它們提供了一種結構化的方式來管理項目的依賴關系,使得項目的依賴管理變得更加便捷和可靠。 2. 常見的包管理工具有哪些? npm(Node Package Manager):是 Node.js 的默認包管理工…

網絡基礎13--鏈路聚合技術

一、鏈路聚合概述定義將多條物理鏈路捆綁為一條邏輯鏈路&#xff0c;提升帶寬與可靠性。2. 應用場景交換機/路由器/服務器之間的互聯&#xff0c;支持二層&#xff08;數據鏈路層&#xff09;和三層&#xff08;網絡層&#xff09;聚合。二、核心作用增加帶寬聚合鏈路的總帶寬 …

一文講清楚React性能優化

文章目錄一文講清楚React性能優化1. React性能優化概述2. React性能優化2.1 render優化2.2 較少使用內聯函數2.3 使用React Fragments避免額外標記2.4 使用Immutable上代碼2.5 組件懶加載2.6 服務端渲染2.7 其他優化手段一文講清楚React性能優化 1. React性能優化概述 React通…

3.0 - 指針-序列化

一、關于Serialize的使用 可以使用該指令臨時將用戶程序的多個結構化數據項保存到緩沖區中(最好位于全局數據塊中)。用于保存轉換后數據的存儲區的數據類型必需為 ARRAY of BYTE 或 ARRAY of CHAR 相當于把一個struct或其他自定義類型變成一個字節數組。 比如我有好幾個結構體…

【論文精讀】基于共識的分布式量子分解算法用于考慮最優傳輸線切換的安全約束機組組合

本次分析的論文《Consensus‐Based Distributed Quantum Decomposition Algorithm for Security‐Constrained Unit Commitment Considering Optimal Transmission Switching》于2025年6月25日在《Advanced Quantum Technologies》期刊上公開發表。本文提出了一個新的基于共識的…

MyBatis-Flex代碼生成

引入依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok<…

知網論文批量下載pdf格式論文,油猴腳本

任務描述 今天收到一個任務&#xff0c;在知網上&#xff0c;把一位專家所有的論文全都下載下來&#xff0c;要保存為PDF格式。 知網不支持批量導出PDF格式論文。一個一個下載PDF&#xff0c;太繁瑣了。 解決方案&#xff1a;找到一個油猴腳本&#xff0c;這個腳本可以從知網…

低代碼平臺:驅動項目管理敏捷開發新范式

隨著企業數字化轉型加速&#xff0c;項目管理系統已從單一任務跟蹤工具到集成流程自動化、資源調度、跨團隊協作與風險監控的綜合平臺&#xff0c;項目管理系統的功能復雜度持續提升。然而&#xff0c;根據Gartner 2024年研究報告顯示&#xff0c;約60%的項目管理系統因未能有效…

圖機器學習(11)——鏈接預測

圖機器學習&#xff08;11&#xff09;——鏈接預測0. 鏈接預測1. 基于相似性的方法1.1 基于指標的方法1.2 基于社區的方法2. 基于嵌入的方法0. 鏈接預測 鏈接預測 (link prediction)&#xff0c;也稱為圖補全&#xff0c;是處理圖時常見的問題。具體而言&#xff0c;給定一個…

簡單2步配置CadenceSkill開發編輯器,支持關鍵字高亮

Cadence 使用過程中難免會與skill打交道&#xff0c;有時候網上找到的開源skill&#xff0c;想要查看或者編輯一下&#xff0c;常規的txt編輯器沒有關鍵字高亮&#xff0c;看起來極為不方便。 利用Sublime Text可以很快速配置出支持skill關鍵字高亮的編輯器。 一、安裝 Sublime…

Leetcode刷題營第三十三題:對稱二叉樹

101. 對稱二叉樹 給你一個二叉樹的根節點 root &#xff0c; 檢查它是否軸對稱。 示例 1&#xff1a; 輸入&#xff1a;root [1,2,2,3,4,4,3] 輸出&#xff1a;true示例 2&#xff1a; 輸入&#xff1a;root [1,2,2,null,3,null,3] 輸出&#xff1a;false 提示&#xff1a;…

day055-Dockerfile與常用指令

文章目錄0. 老男孩思想-女性的第一需求1. Dockerfile1.1 Dockerfile的基本結構1.2 案例-制作小鳥飛飛鏡像1.2.1 編寫Dockerfile文件1.2.2 構建鏡像1.2.3 啟動容器1.3 Dockerfile常用指令1.4 面試題&#xff1a;Dockerfile中CMD和ENTRYPOINT的區別&#xff1f;1.5 案例-制作zrlo…

Spring Boot 應用優雅停機與資源清理:深入理解關閉鉤子

在開發和部署 Spring Boot 應用程序時&#xff0c;除了關注其啟動和運行&#xff0c;理解如何實現**優雅停機&#xff08;Graceful Shutdown&#xff09;**也同樣至關重要。優雅停機意味著在應用程序關閉時&#xff0c;能夠有序地釋放資源、完成正在進行的任務&#xff0c;并避…

淘寶扭蛋機小程序開發:重構電商娛樂化體驗的新范式

在電商行業同質化競爭加劇的當下&#xff0c;消費者對購物體驗的期待已從“功能滿足”轉向“情感共鳴”。淘寶扭蛋機小程序憑借“盲盒式隨機獎勵游戲化交互”的創新模式&#xff0c;成為撬動年輕用戶消費力的新支點。其開發邏輯不僅是對傳統電商的升級&#xff0c;更是對“娛樂…

YOLO演變史(一)

在YOLOV1發布后&#xff0c;作者并沒有滿足于此&#xff0c;而是持續對YOLO進行了改進。 YOLOV2&#xff1a;Better, Faster, Stronger YOLOv2&#xff08;又稱YOLO9000&#xff09;發表于2017年CVPR&#xff0c;是YOLO系列的第二代版本。其論文標題“Better, Faster, Stronger…

專題:2025智能體研究報告|附70份報告PDF、原數據表匯總下載

原文鏈接&#xff1a;https://tecdat.cn/?p43035 智能體正在改寫商業規則&#xff1a;某城商行的智能客服用公有云部署&#xff0c;把單筆交互成本從5.7元砍到1.2元&#xff0c;投訴率直降42%&#xff08;《賽迪智庫&#xff1a;2025全球智能體進展報告》P24&#xff09;&…

Axios 完整功能介紹和完整示例演示

Axios 是一個基于 Promise 的現代化 HTTP 客戶端庫&#xff0c;用于瀏覽器和 Node.js 環境。它提供了簡潔的 API 和強大的功能&#xff0c;是前端開發中最常用的網絡請求工具之一。核心功能 瀏覽器 & Node.js 雙平臺支持 瀏覽器中使用 XMLHttpRequestNode.js 中使用 http 模…

math.h函數

math.c函數作用 1. 基本三角函數&#xff08;參數為弧度&#xff09; sin(double x)&#xff1a;計算正弦值。cos(double x)&#xff1a;計算余弦值。tan(double x)&#xff1a;計算正切值。asin(double x)&#xff1a;反正弦&#xff08;返回值范圍&#xff1a;[-π/2, π/2]&…

在Next.js里玩轉pdf預覽

1.背景在項目開發中&#xff0c;pdf預覽是一個很常見的業務。各大公司為了保護自己的知識產權&#xff0c;也會對pdf預覽進行限制&#xff0c;比如&#xff1a;不允許下載、打印&#xff0c;不允許提取文字等等。要想在實現預覽功能的基礎上還要附加這些限制&#xff0c;有很多…