首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

LeetCode ZigZag Conversion:Z 字形變換 O(n) 線性掃描解法

     編輯:關於C++

題目描述

將字符串按 Z 字形(N 字形)排列在指定行數中,然後按行讀取生成新字符串。例如 "PAYPALISHIRING",3 行排列:

P   A   H   N
A P L S I I G
Y   I   R

按行讀取得:"PAHNAPLSIIGYIR"

規律分析

觀察每行字符在原字符串中的索引規律:

  • 第一行 (i=0):索引間隔 2*(nRows-1)
  • 最後一行 (i=nRows-1):同上
  • 中間行 (0 < i < nRows-1):每個循環週期內有兩個字符,索引差分別為 2*(nRows-1-i) 和 2*i

O(n) 線性掃描算法

直接按行輸出,無需構建二維數組:

class Solution {
public:
    string convert(string s, int nRows) {
        if (nRows <= 1) return s;
        string ans;
        int len = s.length();
        
        for (int i = 0; i < nRows; ++i) {
            int cur = i;
            while (cur < len) {
                ans += s[cur];  // 主字符
                // 中間行添加對角字符
                if (i != 0 && i != nRows-1) {
                    int diag = cur + 2 * (nRows - 1 - i);
                    if (diag < len) ans += s[diag];
                }
                cur += 2 * (nRows - 1);  // 下一週期
            }
        }
        return ans;
    }
};

關鍵點解析

  1. 週期長度:cycle = 2 * (nRows - 1)
  2. 首尾行:每週期僅 1 個字符,步長 cycle
  3. 中間行:每週期 2 個字符,位置分別為 cur 和 cur + 2*(nRows-1-i)
  4. 邊界檢查:對角字符索引可能越界,需判斷 diag < len

複雜度

  • 時間:O(n),每個字符恰好訪問一次
  • 空間:O(n),結果字符串

測試示例

輸入:"PAYPALISHIRING", 3
輸出:"PAHNAPLSIIGYIR"

輸入:"ABCD", 2
輸出:"ACBD"  (A C / B D)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved