【LeetCode】6. Z 字形變換

文章目錄

  • 6. Z 字形變換
    • 題目描述
    • 示例 1:
    • 示例 2:
    • 示例 3:
    • 提示:
    • 解題思路
      • 算法分析
      • 問題本質分析
      • Z字形排列過程詳解
      • Z字形排列可視化
      • 方向控制策略
      • 數學規律法詳解
      • 各種解法對比
      • 算法流程圖
      • 邊界情況處理
      • 時間復雜度分析
      • 空間復雜度分析
      • 關鍵優化點
      • 實際應用場景
      • 測試用例設計
      • 代碼實現要點
    • 完整題解代碼

6. Z 字形變換

題目描述

將一個給定字符串 s 根據給定的行數 numRows ,以從上往下、從左到右進行 Z 字形排列。

比如輸入字符串為 “PAYPALISHIRING” 行數為 3 時,排列如下:

P A H N
A P L S I I G
Y I R
之后,你的輸出需要從左往右逐行讀取,產生出一個新的字符串,比如:“PAHNAPLSIIGYIR”。

請你實現這個將字符串進行指定行數變換的函數:

string convert(string s, int numRows);

示例 1:

輸入:s = “PAYPALISHIRING”, numRows = 3
輸出:“PAHNAPLSIIGYIR”

示例 2:

輸入:s = “PAYPALISHIRING”, numRows = 4
輸出:“PINALSIGYAHRPI”
解釋:
P I N
A L S I G
Y A H R
P I

示例 3:

輸入:s = “A”, numRows = 1
輸出:“A”

提示:

  • 1 <= s.length <= 1000
  • s 由英文字母(小寫和大寫)、‘,’ 和 ‘.’ 組成
  • 1 <= numRows <= 1000

解題思路

這道題要求將字符串按Z字形排列,然后按行讀取。這是一個字符串處理的經典問題。

算法分析

這道題的核心思想是模擬Z字形排列過程,主要解法包括:

  1. 模擬法:實際構建Z字形矩陣,然后按行讀取
  2. 方向控制法:使用方向變量控制字符放置的行數
  3. 數學規律法:利用Z字形的數學規律直接計算字符位置

問題本質分析

Z字形變換
字符串重排問題
Z字形排列
按行讀取
垂直向下填充
斜向向上填充
逐行連接結果
行索引遞增
行索引遞減
最終輸出字符串
到達底部改變方向
到達頂部改變方向
方向控制邏輯

Z字形排列過程詳解

輸入字符串和行數
創建numRows個字符串構建器
初始化當前行索引和方向
遍歷字符串字符
將字符添加到當前行
更新行索引
是否到達邊界?
改變方向
繼續下一字符
還有字符?
按行連接結果
返回最終字符串
currentRow = 0, direction = 1
currentRow += direction
currentRow == 0 或 numRows-1
direction = -direction

Z字形排列可視化

輸入: 'PAYPALISHIRING', numRows = 3
Z字形排列過程
第1步: P → 第0行
第2步: A → 第1行
第3步: Y → 第2行
第4步: P → 第1行 (方向改變)
第5步: A → 第0行 (方向改變)
第6步: L → 第1行
第7步: I → 第2行
繼續填充...
最終排列:
P A H N
A P L S I I G
Y I R
按行讀取: PAHNAPLSIIGYIR

方向控制策略

方向控制策略
初始狀態
向下填充階段
到達底部
向上填充階段
到達頂部
currentRow = 0, direction = 1
currentRow += 1
currentRow == numRows-1
direction = -1
currentRow -= 1
currentRow == 0
direction = 1

數學規律法詳解

數學規律法
周期長度計算
垂直字符位置
斜向字符位置
cycleLen = 2*numRows - 2
第row行: i = row, row+cycleLen, row+2*cycleLen...
斜向位置: i + cycleLen - 2*row
第一行和最后一行只有垂直字符
中間行有垂直和斜向字符
需要檢查邊界條件
簡化處理邏輯
雙重循環填充

各種解法對比

解法對比
模擬法
方向控制法
數學規律法
時間O_n空間O_n*numRows
時間O_n空間O_n
時間O_n空間O_n
直觀易懂
空間效率高
性能最優
適合優化

算法流程圖

flowchart TDA[開始] --> B{numRows == 1?}B -->|是| C[直接返回原字符串]B -->|否| D{numRows >= len(s)?}D -->|是| CD -->|否| E[創建numRows個字符串構建器]E --> F[初始化currentRow=0, direction=1]F --> G[遍歷字符串字符]G --> H[將字符添加到當前行]H --> I[更新行索引]I --> J{到達邊界?}J -->|是| K[改變方向]J -->|否| L{還有字符?}K --> LL -->|是| GL -->|否| M[按行連接結果]M --> N[返回最終字符串]C --> O[結束]N --> O

邊界情況處理

graph TDA[邊界情況] --> B[numRows = 1]A --> C[numRows >= len(s)]A --> D[空字符串]A --> E[單字符字符串]B --> F[直接返回原字符串]C --> FD --> G[返回空字符串]E --> H[正常處理]F --> I[避免不必要的計算]G --> IH --> I

時間復雜度分析

時間復雜度分析
字符遍歷
每個字符處理O_1
總時間O_n
n是字符串長度
線性時間復雜度
最優解法

空間復雜度分析

空間復雜度分析
額外空間使用
字符串構建器數組
空間O_n
n是字符串長度
空間效率合理
可接受范圍

關鍵優化點

優化策略
提前返回
字符串構建器
方向控制優化
邊界情況直接返回
避免字符串拼接開銷
減少條件判斷
提高執行效率

實際應用場景

應用場景
文本排版
數據可視化
密碼學
圖像處理
文本分欄顯示
數據表格排列
字符重排加密
像素矩陣變換
核心算法組件

測試用例設計

graph TDA[測試用例] --> B[基礎功能]A --> C[邊界情況]A --> D[性能測試]B --> E[多行Z字形]B --> F[單行情況]B --> G[不同字符串長度]C --> H[numRows = 1]C --> I[numRows >= len(s)]C --> J[空字符串]D --> K[最大長度字符串]D --> L[最大行數]E --> M[驗證正確性]F --> MG --> MH --> MI --> MJ --> MK --> N[驗證性能]L --> N

代碼實現要點

  1. 方向控制邏輯

    • 使用direction變量控制行索引變化
    • 在邊界處改變方向
  2. 字符串構建器

    • 使用strings.Builder提高效率
    • 避免頻繁的字符串拼接
  3. 邊界條件處理

    • numRows = 1時直接返回
    • numRows >= len(s)時直接返回
  4. 行索引管理

    • 當前行索引范圍:0 到 numRows-1
    • 方向改變條件:到達頂部或底部
  5. 結果構建

    • 按行順序連接所有行的內容
    • 使用strings.Builder提高效率

這個問題的關鍵在于理解Z字形的排列規律掌握方向控制技巧,通過模擬Z字形的填充過程,實現字符串的重排和重組。

完整題解代碼

package mainimport ("fmt""strings"
)// convert Z字形變換
// 時間復雜度: O(n),其中n是字符串長度
// 空間復雜度: O(n)
func convert(s string, numRows int) string {if numRows == 1 || numRows >= len(s) {return s}// 創建numRows個字符串構建器rows := make([]strings.Builder, numRows)// 當前行索引和方向currentRow := 0direction := 1 // 1表示向下,-1表示向上// 遍歷字符串,按Z字形填充for _, char := range s {// 將當前字符添加到當前行rows[currentRow].WriteByte(byte(char))// 更新行索引currentRow += direction// 如果到達邊界,改變方向if currentRow == 0 || currentRow == numRows-1 {direction = -direction}}// 將所有行連接起來var result strings.Builderfor _, row := range rows {result.WriteString(row.String())}return result.String()
}// convertOptimized 優化版本,使用數學規律
// 時間復雜度: O(n)
// 空間復雜度: O(n)
func convertOptimized(s string, numRows int) string {if numRows == 1 || numRows >= len(s) {return s}var result strings.Buildern := len(s)// 第一行和最后一行的字符間隔cycleLen := 2*numRows - 2// 逐行構建結果for row := 0; row < numRows; row++ {for i := row; i < n; i += cycleLen {// 添加垂直方向的字符result.WriteByte(s[i])// 如果不是第一行和最后一行,還需要添加斜向的字符if row != 0 && row != numRows-1 {// 計算斜向字符的位置diagonalIndex := i + cycleLen - 2*rowif diagonalIndex < n {result.WriteByte(s[diagonalIndex])}}}}return result.String()
}// convertSimulation 模擬法:實際構建Z字形矩陣
// 時間復雜度: O(n)
// 空間復雜度: O(n*numRows)
func convertSimulation(s string, numRows int) string {if numRows == 1 || numRows >= len(s) {return s}// 創建Z字形矩陣matrix := make([][]byte, numRows)for i := range matrix {matrix[i] = make([]byte, 0)}currentRow := 0direction := 1// 填充矩陣for _, char := range s {matrix[currentRow] = append(matrix[currentRow], byte(char))currentRow += directionif currentRow == 0 || currentRow == numRows-1 {direction = -direction}}// 按行讀取結果var result strings.Builderfor _, row := range matrix {result.Write(row)}return result.String()
}func main() {// 測試用例1s1 := "PAYPALISHIRING"numRows1 := 3result1 := convert(s1, numRows1)fmt.Printf("示例1: s = \"%s\", numRows = %d\n", s1, numRows1)fmt.Printf("輸出: \"%s\"\n", result1)fmt.Printf("期望: \"PAHNAPLSIIGYIR\"\n")fmt.Printf("結果: %t\n", result1 == "PAHNAPLSIIGYIR")fmt.Println()// 測試用例2s2 := "PAYPALISHIRING"numRows2 := 4result2 := convert(s2, numRows2)fmt.Printf("示例2: s = \"%s\", numRows = %d\n", s2, numRows2)fmt.Printf("輸出: \"%s\"\n", result2)fmt.Printf("期望: \"PINALSIGYAHRPI\"\n")fmt.Printf("結果: %t\n", result2 == "PINALSIGYAHRPI")fmt.Println()// 測試用例3s3 := "A"numRows3 := 1result3 := convert(s3, numRows3)fmt.Printf("示例3: s = \"%s\", numRows = %d\n", s3, numRows3)fmt.Printf("輸出: \"%s\"\n", result3)fmt.Printf("期望: \"A\"\n")fmt.Printf("結果: %t\n", result3 == "A")fmt.Println()// 額外測試用例s4 := "AB"numRows4 := 1result4 := convert(s4, numRows4)fmt.Printf("額外測試: s = \"%s\", numRows = %d\n", s4, numRows4)fmt.Printf("輸出: \"%s\"\n", result4)fmt.Printf("期望: \"AB\"\n")fmt.Printf("結果: %t\n", result4 == "AB")fmt.Println()// 測試優化版本fmt.Println("=== 優化版本測試 ===")result1Opt := convertOptimized(s1, numRows1)result2Opt := convertOptimized(s2, numRows2)fmt.Printf("優化版本示例1: %s\n", result1Opt)fmt.Printf("優化版本示例2: %s\n", result2Opt)fmt.Printf("結果一致: %t\n", result1Opt == result1 && result2Opt == result2)fmt.Println()// 測試模擬版本fmt.Println("=== 模擬版本測試 ===")result1Sim := convertSimulation(s1, numRows1)result2Sim := convertSimulation(s2, numRows2)fmt.Printf("模擬版本示例1: %s\n", result1Sim)fmt.Printf("模擬版本示例2: %s\n", result2Sim)fmt.Printf("結果一致: %t\n", result1Sim == result1 && result2Sim == result2)
}

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

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

相關文章

spring文件下載的方式

spring文件下載的方式方式一:通過ResponseEntity<Resource> 方式來下載方式二:通過ResponseEntity<StreamingResponseBody> 方式來下載方式三:通過Servlet原生下載方式四:通過ResponseEntity<byte[]> 方式來下載四種下載方式的對比1、核心特性對比2、典型場景…

寫一個redis客戶端軟件,參考 Another Redis Desktop Manager 的設計風格。

一個基于 Electron 開發的現代化 Redis 桌面客戶端&#xff0c;參考 Another Redis Desktop Manager 的設計風格。 github倉庫地址 https://github.com/henkuoai/redis-man-pc

Web3: DeFi借貸的安全基石, 了解喂價與清算機制的原理與重要性

今天我們要聊一個DeFi世界里至關重要&#xff0c;但又時常被誤解的話題&#xff1a;為什么DeFi協議需要定期更新喂價和執行清算&#xff1f; 如果大家參與過DeFi借貸&#xff0c;大家可能看到過“清算”這個詞&#xff0c;甚至會有點談虎色變。但實際上&#xff0c;清算和為其提…

「iOS」————響應者鏈與事件傳遞鏈

iOS學習響應者鏈和事件傳遞鏈傳遞鏈&#xff1a;hitTest:withEvent**pointInside:withEvent**響應鏈第一響應者和最佳響應者觸摸事件&#xff08;UITouch&#xff09;UIGestureRecognizer&#xff08;手勢識別器&#xff09;響應者鏈和事件傳遞鏈 iOS事件的主要由&#xff1a;…

修復圖像、視頻和3D場景的AI工具–Inpaint Anything

TL; DR&#xff1a;用戶可以通過單擊來選擇圖像中的任何對象。借助強大的視覺模型&#xff0c;例如SAM、LaMa和穩定擴散 (SD)&#xff0c;Inpaint Anything能夠順利地移除對象&#xff08;即Remove Anything&#xff09;。此外&#xff0c;在用戶輸入文本的提示下&#xff0c;I…

java -jar xxx.jar 提示xxx.jar中沒有主清單屬性報錯解決方案

xxx.jar 中沒有主清單屬性 &#xff08;no main manifest attribute&#xff09;解決方案 java -jar xxx.jar 提示xxx.jar中沒有主清單屬性報錯解決方案 這個錯通常出現在你用 java -jar xxx.jar 啟動&#xff0c;但 JAR 的 META-INF/MANIFEST.MF 里沒有 Main-Class 條目&#…

Myqsl建立庫表練習

目錄 一、windows中選擇一種方式安裝Mysql8.0 二、新建產品庫mydb6_product 1. 新建3張表如下&#xff1a; 1&#xff09;employees表 2&#xff09;orders表 3&#xff09;invoices表 三、新建員工庫mydb8_worker&#xff0c;添加自定義表內容并插入數據 1. 新建庫表 2. 插…

STM32 輸入捕獲,串口打印,定時器,中斷綜合運用

實驗目的 使用定時器 2 通道 2 來捕獲按鍵 2 按下時間&#xff0c;并通過串口打印。 計一個數的時間&#xff1a;1us&#xff0c;PSC71&#xff0c;ARR65535 下降沿捕獲、輸入通道 2 映射在 TI2 上、不分頻、不濾波輸入捕獲原理定時器輸入捕獲實驗配置步驟測量按鍵按下時長思路…

Nacos-2--Nacos1.x版本的通信原理

在Nacos 1.x版本中&#xff0c;客戶端長輪詢&#xff08;Long Polling&#xff09;和服務端UDP主動推送是兩種不同的機制&#xff0c;分別用于配置管理和服務發現場景。它們的核心目標都是實現動態更新的實時感知&#xff0c;但實現方式、數據內容和適用場景完全不同。 1、長輪…

機器學習——09 聚類算法

1 聚類算法聚類算法&#xff1a; 是一種無監督學習算法&#xff0c;它不需要預先知道數據的類別信息&#xff0c;而是根據樣本之間的相似性&#xff0c;將樣本劃分到不同的類別中&#xff1b;不同的相似度計算方法&#xff0c;會得到不同的聚類結果&#xff0c;常用的相似度計算…

生成式AI應用生態的爆發與專業化演進:從零和博弈到正和共贏

2025年,生成式AI產業規模已突破7000億元,全球生成式AI市場規模預計在2028年達到2842億美元(IDC數據)。在這場技術革命中,AI基礎模型的分化已證明:差異化競爭而非同質化替代,才是推動產業發展的核心邏輯。如今,這一規律正從基礎模型層向應用生成平臺層蔓延——Lovable、…

Mysql——Sql的執行過程

目錄 一、Sql的執行過程流程圖解 二、Sql的執行過程流程 1.2.1、建立連接 1.2.2、服務層(緩存、解析器、預處理器、優化器、執行器) 1.2.2.1、緩存 1.2.2.2、解析器 1.2.2.3、預處理器 1.2.2.4、優化器 1.2.2.5、執行器 1.2.3、引擎層 一、Sql的執行過程流程圖解 Sql的執行過…

【Axure高保真原型】地圖路線和定位

今天和大家分享地圖路線和定位的原型模版&#xff0c;載入后&#xff0c;可以查看汽車行進路線和所在定位 提供了停靠和不停靠站點兩個案例&#xff0c;具體效果可以打開下方原型地址體驗或者點擊下方視頻觀看 【Axure高保真原型】地圖路線和定位【原型預覽含下載地址】 https…

【96頁PPT】華為IPD流程管理詳細版(附下載方式)

篇幅所限&#xff0c;本文只提供部分資料內容&#xff0c;完整資料請看下面鏈接 https://download.csdn.net/download/2501_92808811/91633108 資料解讀&#xff1a;華為IPD流程管理詳細版 詳細資料請看本解讀文章的最后內容 華為的集成產品開發&#xff08;IPD&#xff09;…

深度解析Mysql的開窗函數(易懂版)

SQL 開窗函數&#xff08;Window Function&#xff09;是一種強大的分析工具&#xff0c;它能在保留原有數據行的基礎上&#xff0c;對 "窗口"&#xff08;指定范圍的行集合&#xff09;進行聚合、排名或分析計算&#xff0c;解決了傳統GROUP BY聚合會合并行的局限性…

Java靜態代理和動態代理

Java靜態代理和動態代理 靜態代理 現在有一個計算類&#xff0c;有四個方法&#xff0c;加減乘除&#xff0c;如果需要給這四個方法都加上同一個邏輯&#xff0c;可以創建一個類作為代理類&#xff0c;把計算類注入到這個類中&#xff0c;然后再代理類中定義方法&#xff0c;并…

MySQL——MySQL引擎層BufferPool工作過程原理

目錄一、MySQL引擎層BufferPool工作過程圖解二、MySQL引擎層BufferPool工作過程原理一、MySQL引擎層BufferPool工作過程圖解 圖解 二、MySQL引擎層BufferPool工作過程原理 首先關閉自動提交&#xff0c;執行一條修改語句。 SET AUTOCOMMIT 0; update employees set name張三…

Python初學者筆記第二十二期 -- (JSON數據解析)

第31節課 JSON數據解析 1.JSON基礎概念 JSON 是一種輕量級的數據交換格式&#xff08;另一個叫XML&#xff09;&#xff0c;具有簡潔、易讀的特點&#xff0c;并且在不同編程語言之間能很好地實現數據傳遞。在 Python 中&#xff0c;json模塊能夠實現 Python 數據類型與 JSON 數…

基于多模態大模型的個性化學習路徑生成系統研究

摘要 隨著互聯網技術的迅猛發展&#xff0c;個性化學習路徑生成系統的研究在教育領域日益凸顯其重要性。本研究聚焦于基于多模態大模型的個性化學習路徑生成系統&#xff0c;旨在通過整合多模態數據&#xff0c;為學習者提供更加精準、個性化的學習路徑。多模態大模型&#xf…

ESP32 燒錄固件失敗原因排除

ESP32 燒錄固件時&#xff0c;有哪些特殊引腳需要注意電平狀態的在 ESP32 燒錄固件時&#xff0c;有幾個關鍵引腳的電平狀態會直接影響燒錄過程&#xff0c;需要特別注意&#xff1a;GPIO0&#xff08;BOOT 引腳&#xff09;&#xff1a;燒錄模式&#xff1a;需要拉低&#xff…