每日一題——順時針旋轉矩陣

順時針旋轉矩陣

目錄

  • 一、問題描述
  • 二、解題思路
    • 1. 原地旋轉矩陣
    • 2. 旋轉邏輯
    • 3. 代碼實現
  • 三、代碼解析
    • 1. 參數說明
    • 2. 原地旋轉邏輯
    • 3. 返回矩陣
  • 四、示例測試代碼
  • 五、復雜度分析
    • 1. 時間復雜度
    • 2. 空間復雜度

一、問題描述

以下是內容轉換為 CSDN 的 Markdown 格式:


問題描述

給定一個 N * N\的整數矩陣,請編寫一個算法將其順時針旋轉 90 度。旋轉后的矩陣需要返回。例如,給定矩陣:

1  2  3 
4  5  6 
7  8  9 

旋轉 90 度后應變為:

7  4  1 
8  5  2 
9  6  3 

說明

  • 矩陣的旋轉操作是原地進行的,即不額外分配空間。
  • 示例中的矩陣旋轉后,行和列的值發生了相應的變化。

數據范圍

  • (0 < n < 300)
  • 矩陣中的值滿足 (0 \leq val \leq 1000)

復雜度要求

  • 空間復雜度:(O(1))
  • 時間復雜度:(O(N^2))

二、解題思路

1. 原地旋轉矩陣

為了滿足空間復雜度 (O(1)) 的要求,我們需要在原矩陣上直接進行操作,而不是使用額外的空間。具體步驟如下:

  1. 分層旋轉:矩陣可以分為多層,每一層從外到內逐步旋轉。
  2. 旋轉步驟
    • 保存左上角的值。
    • 按順時針方向依次交換四個位置的值。

2. 旋轉邏輯

對于每個元素 ((i, j)),其旋轉后的位置可以通過以下公式計算:

  • 新行索引 (i’ = j)
  • 新列索引 (j’ = N - i - 1)

3. 代碼實現

以下是完整的C語言實現代碼,包含詳細的注釋:

#include <stdio.h>
#include <stdlib.h>/*** 順時針旋轉矩陣90度* @param mat: 輸入矩陣* @param matRowLen: 矩陣的行數* @param matColLen: 矩陣的列數(每行的長度)* @param n: 矩陣的階數(n x n)* @param returnSize: 返回矩陣的行數* @param returnColumnSizes: 返回矩陣的列數(每行的長度)* @return: 旋轉后的矩陣*/
int** rotateMatrix(int** mat, int matRowLen, int* matColLen, int n,int* returnSize, int** returnColumnSizes) {// 設置返回矩陣的行數和列數*returnSize = n;  // 設置返回矩陣的行數為n*returnColumnSizes = (int*)malloc(n * sizeof(int));  // 分配內存用于存儲每行的列數for (int i = 0; i < n; i++) {(*returnColumnSizes)[i] = n;  // 每行的列數也為n}// 原地旋轉矩陣for (int layer = 0; layer < n / 2; layer++) {  // 遍歷每一層,從外層到內層int first = layer;  // 當前層的起始索引int last = n - layer - 1;  // 當前層的結束索引for (int i = first; i < last; i++) {  // 遍歷當前層的每個元素int gap = i - first;  // 當前元素與起始索引的偏移量int temp = mat[first][i];  // 保存左上角的值// 左上 <- 左下mat[first][i] = mat[last - gap][first];// 左下 <- 右下mat[last - gap][first] = mat[last][last - gap];// 右下 <- 右上mat[last][last - gap] = mat[i][last];// 右上 <- 左上(保存的值)mat[i][last] = temp;}}// 返回原地旋轉后的矩陣return mat;
}

三、代碼解析

1. 參數說明

  • mat:輸入的二維矩陣。
  • matRowLen:矩陣的行數。
  • matColLen:矩陣的列數(每行的長度)。
  • n:矩陣的階數(矩陣是 (n \times n) 的)。
  • returnSize:返回矩陣的行數(通過指針返回)。
  • returnColumnSizes:返回矩陣的列數(每行的長度,通過指針返回)。

2. 原地旋轉邏輯

  • 分層旋轉:矩陣可以分為多層,每一層從外到內逐步旋轉。
  • 旋轉步驟
    1. 保存左上角的值:將左上角的值保存到臨時變量 temp
    2. 左上 <- 左下:將左下角的值移動到左上角。
    3. 左下 <- 右下:將右下角的值移動到左下角。
    4. 右下 <- 右上:將右上角的值移動到右下角。
    5. 右上 <- 左上(保存的值):將保存的左上角的值移動到右上角。

3. 返回矩陣

  • 設置返回矩陣的行數和列數:
    • *returnSize = n:返回矩陣的行數。
    • *returnColumnSizes:返回矩陣的列數(每行的長度)。
  • 返回原地旋轉后的矩陣 mat

四、示例測試代碼

以下是測試代碼,用于驗證 rotateMatrix 函數的正確性:

#include <stdio.h>int main() {int n = 3;int mat[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};int* matPtr[3];for (int i = 0; i < n; i++) {matPtr[i] = mat[i];}int returnSize;int* returnColumnSizes;int** rotated = rotateMatrix(matPtr, n, NULL, n, &returnSize, &returnColumnSizes);printf("Rotated Matrix:\n");for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {printf("%d ", rotated[i][j]);}printf("\n");}free(returnColumnSizes);return 0;
}

輸出

輸入:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3
輸出:
Rotated Matrix:
7 4 1 
8 5 2 
9 6 3 

五、復雜度分析

1. 時間復雜度

  • 每個元素只被訪問一次,時間復雜度為 (O(N^2))。

2. 空間復雜度

  • 除了輸入矩陣外,沒有使用額外的空間,空間復雜度為 (O(1))。

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

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

相關文章

接雨水的算法

題目 代碼 # 接雨水算法 def trap(height):# 1. 特殊情況&#xff1a;數組為空 則返回0if not height:return 0n len(height)# 2. 初始化左右指針&#xff0c;左右最大值&#xff0c;結果left, right 0, n - 1# maxleft代表左邊最大值&#xff0c;maxright代表右邊最大值max…

會話對象 HttpSession 二、HttpSession失效

session失效有如下幾個原因&#xff1a; session.invalidate()方法注銷sessionsession超時 <session-config><!-- session的超時時間&#xff0c;以分鐘為單位 --><session-timeout>1</session-timeout> </session-config>Cookie被禁用

Jenkins 創建 Node 到 Windows

Jenkins 創建 Node 到 Windows 一. 新建 Node Dashboard -> Manage Jenkins -> Manage Nodes and Clouds Dashboard -> Nodes -> New Node 二. 配置節點 Node&#xff1a;節點名 Description&#xff1a;節點描述 Number of executors&#xff1a;節點最大同…

Opengl常用緩沖對象功能介紹及使用示例(C++實現)

本文整理了常用的opengl緩沖區對象并安排了使用示例 名稱英文全稱作用簡述頂點數組對象Vertex Array Object (VAO)管理 VBO 和 EBO 的配置&#xff0c;存儲頂點屬性設置&#xff0c;簡化渲染流程&#xff0c;避免重復設置狀態頂點緩沖區對象Vertex Buffer Object (VBO)存儲頂點…

矩陣加減乘除的意義與應用

矩陣加法 數學意義 線性空間的封閉性線性變換的疊加矩陣分解與表示 實際應用 數據聚合與統計圖像處理與計算機視覺物理學與工程學動態系統與優化經濟學與運籌學信號處理與通信游戲開發與計算機圖形學環境科學與地理信息矩陣加法的關鍵特點 矩陣減法 數學意義線性空間封閉性 線…

【Redis原理】底層數據結構 五種數據類型

文章目錄 動態字符串SDS(simple dynamic string )SDS結構定義SDS動態擴容 IntSetIntSet 結構定義IntSet的升級 DictDict結構定義Dict的擴容Dict的收縮Dict 的rehash ZipListZipListEntryencoding 編碼字符串整數 ZipList的連鎖更新問題 QuickListQuickList源碼 SkipListRedisOb…

微信小程序 - 頁面跳轉(wx.navigateTo、wx.redirectTo、wx.switchTab、wx.reLaunch)

API 跳轉 1、wx.navigateTo &#xff08;1&#xff09;基本介紹 功能&#xff1a;保留當前頁面&#xff0c;跳轉到應用內的某個頁面&#xff0c;使用該方法跳轉后可以通過返回按鈕返回到原頁面 使用場景&#xff1a;適用于需要保留當前頁面狀態&#xff0c;后續還需返回的情…

Qt 中集成mqtt協議

一&#xff0c;引入qmqtt 庫 我是將整個頭文件/源文件都添加到了工程中進行編譯&#xff0c;這樣 跨平臺時 方便&#xff0c;直接編譯就行了。 原始倉庫路徑&#xff1a;https://github.com/emqx/qmqtt/tree/master 二&#xff0c;使用 聲明一個單例類&#xff0c;將訂閱到…

分布式之Raft算法

參考&#xff1a; 分布式算法 - Raft算法 | Java 全棧知識體系 Raft 算法詳解 | JavaGuide 分布式 | CS-Notes 面試筆記

安裝PHPStudy 并搭建DVWA靶場

目錄 一、PHPStudy 簡介 二、DVWA 簡介 三、安裝 PHPStudy 四&#xff1a;安裝 DVWA 一、PHPStudy 簡介 phpstudy傻瓜式的一鍵啟動&#xff0c;支持WAMP、WNMP、LAMP、LNMP&#xff0c;一鍵切換環境&#xff08;nginxapahce&#xff09;,一鍵切換PHP版本&#xff08;5.1-7…

孜然單授權系統V2.0PHP授權系統

孜然單授權V1.0系統&#xff0c;延續了2022年開發的孜然多應用授權系統V2.0 變更&#xff1a;多應用變單系統&#xff0c;去除沒用的垃圾代碼&#xff0c;從0開發&#xff0c;去除了一些沒用的功能 完善了開發文檔&#xff0c;之前那套是我寫著玩的屎山代碼&#xff0c;V1.0將展…

紅帽7基于kickstart搭建PXE環境

Kickstart 文件是一種配置文件&#xff0c;用于定義 Linux 系統安裝過程中的各種參數&#xff0c;如分區、網絡配置、軟件包選擇等。system-config-kickstart 提供了一個圖形界面&#xff0c;方便用戶快速生成這些配置文件。 用戶可以通過圖形界面進行系統安裝的詳細配置&…

怎么合并主從分支,要注意什么

在 Git 中合并主從分支&#xff08;例如將 feature 分支合并到 main 分支&#xff09;是一個常見操作。以下是具體步驟和注意事項&#xff1a; 合并分支的步驟 切換到主分支 git checkout main確保當前在 main 分支。 拉取最新代碼 git pull origin main確保 main 分支是最…

Java數據結構第十二期:走進二叉樹的奇妙世界(一)

專欄&#xff1a;數據結構(Java版) 個人主頁&#xff1a;手握風云 目錄 一、樹型結構 1.1. 樹的定義 1.2. 樹的基本概念 1.3. 樹的表示形式 二、二叉樹 2.1. 概念 2.2. 兩種特殊的二叉樹 2.3. 二叉樹的性質 2.4. 二叉樹的存儲 三、二叉樹的基本操作 一、樹型結構 1.…

匹配算法:向下就近原則,向下沒有就向上

匹配算法&#xff1a;向下就近原則&#xff0c;向下沒有就向上 實現方式一實現方式二總結 實現方式一 private static List<Integer> findMatches(List<Integer> sourceList, List<Integer> searchValues) {List<Integer> sortedList sourceList.stre…

基于 Python Django 的校園互助平臺(附源碼,文檔)

博主介紹&#xff1a;?Java徐師兄、7年大廠程序員經歷。全網粉絲13w、csdn博客專家、掘金/華為云等平臺優質作者、專注于Java技術領域和畢業項目實戰? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&#x1f3fb; 精彩專欄推薦訂閱&#x1f447;&#x1f3fb; 不…

IP地址 vs 域名:分布式系統中的服務尋址之爭

在分布式系統中&#xff0c;服務之間的通信是核心問題之一。如何高效、穩定地找到目標服務&#xff0c;是每個開發者都需要面對的挑戰。常見的服務尋址方式有兩種&#xff1a;IP地址 和 域名。這兩種方式各有優劣&#xff0c;適用于不同的場景。本文將從性能、穩定性、動態性、…

【技術筆記】Cadence 創建元器件 Pin 引腳的創建與設置

【技術筆記】Cadence 創建元器件 Pin 引腳設置 一、管腳 Pin 放置方式1. 直接放置&#xff08;快捷鍵【Shift】【G】&#xff09;2. 按照Pin陣列放置引腳&#xff08;快捷鍵【Shift】【J】&#xff09;3. 通過Excel表格創建元器件 二、引腳屬性設置1. 創建Pin設置&#xff0c;E…

java面試場景問題

還在補充&#xff0c;這幾天工作忙&#xff0c;閑了會把答案附上去&#xff0c;也歡迎各位大佬評論區討論 1.不用分布式鎖如何防重復提交 方法 1&#xff1a;基于唯一請求 ID&#xff08;冪等 Token&#xff09; 思路&#xff1a;前端生成 一個唯一的 requestId&#xff08;…

Windows11安裝GPU版本Pytorch2.6教程

1: 準備工作 針對已經安裝好的Windows11系統&#xff0c;先檢查Nvidia驅動和使用的CUDA版本情況。先打開Windows PowerShell&#xff0c;通過nvidia-smi命令查看GPU的情況&#xff0c;結果如下圖1所示&#xff0c;從結果中可知使用的CUDA版本為12.8。 圖1&#xff1a;檢測安裝…