题目描述 将一个给定字符串 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
解决方法 C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution {public : std::string convert (std::string s, int numRows) { if (numRows <= 1 || s.length () <= numRows) { return s; } std::vector<std::string> rows (numRows) ; int row = 0 ; int step = 1 ; for (char c : s) { rows[row].push_back (c); if (row == 0 ) { step = 1 ; } else if (row == numRows - 1 ) { step = -1 ; } row += step; } std::string result; for (const std::string& rowStr : rows) { result += rowStr; } return result; } };
结果 执行用时 : 8 ms, 击败 91.30% 使用 C++ 的用户
内存消耗 : 10.46 MB, 击败 58.69% 使用 C++ 的用户
Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class Solution { public String convert (String s, int numRows) { if (numRows <= 1 || s.length() <= numRows) { return s; } StringBuilder[] rows = new StringBuilder [numRows]; for (int i = 0 ; i < numRows; i++) { rows[i] = new StringBuilder (); } int row = 0 ; int step = 1 ; for (char c : s.toCharArray()) { rows[row].append(c); if (row == 0 ) { step = 1 ; } else if (row == numRows - 1 ) { step = -1 ; } row += step; } StringBuilder result = new StringBuilder (); for (StringBuilder rowStr : rows) { result.append(rowStr); } return result.toString(); } }
结果 执行用时 : 4 ms, 击败 86.05% 使用 Java 的用户
内存消耗 : 43.73 MB, 击败 20.70% 使用 Java 的用户
Python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution (object ): def convert (self, s, numRows ): if numRows <= 1 or len (s) <= numRows: return s rows = ['' ] * numRows row = 0 step = 1 for char in s: rows[row] += char if row == 0 : step = 1 elif row == numRows - 1 : step = -1 row += step return '' .join(rows)
结果 执行用时 : 76 ms, 击败 29.33% 使用 Python 的用户
内存消耗 : 13.10 MB, 击败 75.91% 使用 Python 的用户
Python3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution : def convert (self, s: str , numRows: int ) -> str : if numRows <= 1 or len (s) <= numRows: return s rows = ['' ] * numRows row = 0 step = 1 for char in s: rows[row] += char if row == 0 : step = 1 elif row == numRows - 1 : step = -1 row += step return '' .join(rows)
结果 执行用时 : 48 ms, 击败 97.61% 使用 Python3 的用户
内存消耗 : 17.09 MB, 击败 14.32% 使用 Python3 的用户
C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 char * convert (char * s, int numRows) { int n = strlen (s), r = numRows; if (r == 1 || r >= n) { return s; } int t = r * 2 - 2 ; int c = (n + t - 1 ) / t * (r - 1 ); char ** mat = (char **)malloc (sizeof (char *) * r); for (int i = 0 ; i < r; i++) { mat[i] = (char *)malloc (sizeof (char ) * c); memset (mat[i], 0 , sizeof (char ) * c); } for (int i = 0 , x = 0 , y = 0 ; i < n; ++i) { mat[x][y] = s[i]; if (i % t < r - 1 ) { ++x; } else { --x; ++y; } } char * result = (char *)malloc (sizeof (char ) * (n + 1 )); int pos = 0 ; for (int i = 0 ; i < r; i++) { for (int j = 0 ; j < c; j++) { if (mat[i][j]) { result[pos++] = mat[i][j]; } } free (mat[i]); } free (mat); result[n] = '\0' ; strcpy (s, result); free (result); return s; }
结果 执行用时 : 44 ms, 击败 24.86% 使用 C 的用户
内存消耗 : 30.42 MB, 击败 13.58% 使用 C 的用户
C# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class Solution { public string Convert (string s, int numRows ) { if (numRows <= 1 || s.Length <= numRows) { return s; } int n = s.Length; int t = numRows * 2 - 2 ; int c = (n + t - 1 ) / t * (numRows - 1 ); char [,] mat = new char [numRows, c]; int x = 0 , y = 0 ; for (int i = 0 ; i < n; ++i) { mat[x, y] = s[i]; if (i % t < numRows - 1 ) { ++x; } else { --x; ++y; } } string result = "" ; for (int i = 0 ; i < numRows; i++) { for (int j = 0 ; j < c; j++) { if (mat[i, j] != '\0' ) { result += mat[i, j]; } } } return result; } }
结果 执行用时 : 88 ms, 击败 49.10% 使用 C# 的用户
内存消耗 : 58.23 MB, 击败 42.19% 使用 C# 的用户
JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 var convert = function (s, numRows ) { if (numRows <= 1 || s.length <= numRows) { return s; } let n = s.length ; let t = numRows * 2 - 2 ; let c = Math .ceil (n / t) * (numRows - 1 ); let mat = new Array (numRows).fill ().map (() => new Array (c).fill ('' )); let x = 0 , y = 0 ; for (let i = 0 ; i < n; ++i) { mat[x][y] = s[i]; if (i % t < numRows - 1 ) { ++x; } else { --x; ++y; } } let result = '' ; for (let i = 0 ; i < numRows; i++) { for (let j = 0 ; j < c; j++) { if (mat[i][j] !== '' ) { result += mat[i][j]; } } } return result; };
结果 执行用时 : 156 ms, 击败 21.61% 使用 JavaScript 的用户
内存消耗 : 64.30 MB, 击败 8.54% 使用 JavaScript 的用户
TypeScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function convert (s : string , numRows : number ): string { if (numRows <= 1 || s.length <= numRows) { return s; } const n : number = s.length ; const t : number = numRows * 2 - 2 ; const c : number = Math .ceil (n / t) * (numRows - 1 ); const mat : string [][] = Array .from ({ length : numRows }, () => Array (c).fill ('' )); let x : number = 0 , y : number = 0 ; for (let i = 0 ; i < n; ++i) { mat[x][y] = s[i]; if (i % t < numRows - 1 ) { ++x; } else { --x; ++y; } } let result : string = '' ; for (let i = 0 ; i < numRows; i++) { for (let j = 0 ; j < c; j++) { if (mat[i][j] !== '' ) { result += mat[i][j]; } } } return result; }
结果 执行用时 : 156 ms, 击败 11.05% 使用 TypeScript 的用户
内存消耗 : 63.39 MB, 击败 5.23% 使用 TypeScript 的用户
PHP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution { function convert ($s , $numRows ) { if ($numRows <= 1 || strlen ($s ) <= $numRows ) { return $s ; } $n = strlen ($s ); $t = $numRows * 2 - 2 ; $c = ceil ($n / $t ) * ($numRows - 1 ); $mat = array_fill (0 , $numRows , array_fill (0 , $c , '' )); $x = 0 ; $y = 0 ; for ($i = 0 ; $i < $n ; ++$i ) { $mat [$x ][$y ] = $s [$i ]; if ($i % $t < $numRows - 1 ) { ++$x ; } else { --$x ; ++$y ; } } $result = '' ; for ($i = 0 ; $i < $numRows ; $i ++) { for ($j = 0 ; $j < $c ; $j ++) { if ($mat [$i ][$j ] !== '' ) { $result .= $mat [$i ][$j ]; } } } return $result ; } }
结果 执行用时 : 276 ms, 击败 6.98% 使用 PHP 的用户
内存消耗 : 35.56 MB, 击败 6.98% 使用 PHP 的用户
Swift 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { func convert (_ s : String , _ numRows : Int ) -> String { if numRows <= 1 || s.count <= numRows { return s } let n = s.count let t = numRows * 2 - 2 let c = Int (ceil(Double (n) / Double (t)) * Double (numRows - 1 )) var mat = Array (repeating: Array (repeating: Character (" " ), count: c), count: numRows) var x = 0 var y = 0 for (i, char) in s.enumerated() { mat[x][y] = char if i % t < numRows - 1 { x += 1 } else { x -= 1 y += 1 } } var result = "" for i in 0 ..< numRows { for j in 0 ..< c { if mat[i][j] != " " { result.append(mat[i][j]) } } } return result } }
结果 执行用时 : 172 ms, 击败 16.22% 使用 Swift 的用户
内存消耗 : 28.77 MB, 击败 5.40% 使用 Swift 的用户
Kotlin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Solution { fun convert (s: String , numRows: Int ) : String { if (numRows <= 1 || s.length <= numRows) { return s } val n = s.length val t = numRows * 2 - 2 val c = ((n + t - 1 ) / t) * (numRows - 1 ) val mat = Array(numRows) { CharArray(c) { ' ' } } var x = 0 var y = 0 for (i in s.indices) { mat[x][y] = s[i] if (i % t < numRows - 1 ) { ++x } else { --x ++y } } var result = "" for (i in 0 until numRows) { for (j in 0 until c) { if (mat[i][j] != ' ' ) { result += mat[i][j] } } } return result } }
结果 执行用时 : 276 ms, 击败 29.79% 使用 Kotlin 的用户
内存消耗 : 39.07 MB, 击败 14.89% 使用 Kotlin 的用户
Dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { String convert(String s, int numRows) { if (s.length == 1 || numRows == 1 || s.length < numRows) { return s; } List <String > rows = List .filled(numRows, '' ); int index = 0 ; int currentRow = 0 ; int zigzagLength = 2 * numRows - 2 ; while (index < s.length) { rows[currentRow] += s[index]; if (index % zigzagLength < numRows - 1 ) { currentRow++; } else { currentRow--; } index++; } return rows.join(); } }
结果 执行用时 : 368 ms, 击败 37.50% 使用 Dart 的用户
内存消耗 : 149.43 MB, 击败 100.00% 使用 Dart 的用户
Go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 func convert (s string , numRows int ) string { if numRows <= 1 || len (s) <= numRows { return s } rows := make ([]string , numRows) index, step := 0 , 1 for i := 0 ; i < len (s); i++ { rows[index] += string (s[i]) if index == 0 { step = 1 } else if index == numRows-1 { step = -1 } index += step } result := "" for _, row := range rows { result += row } return result }
结果 执行用时 : 8 ms, 击败 68.58% 使用 Go 的用户
内存消耗 : 7.21 MB, 击败 27.36% 使用 Go 的用户
Ruby 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def convert (s, num_rows ) return s if num_rows <= 1 | | s.length <= num_rows rows = Array .new(num_rows, "" ) index, step = 0 , 1 s.each_char do |char | rows[index] += char if index == 0 step = 1 elsif index == num_rows - 1 step = -1 end index += step end rows.join end
结果 执行用时 : 96 ms, 击败 100.00% 使用 Ruby 的用户
内存消耗 : 206.76 MB, 击败 -% 使用 Ruby 的用户
Scala 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 object Solution { def convert (s: String , numRows: Int ): String = { if (numRows <= 1 || s.length <= numRows) { return s } val rows = Array .fill(numRows)("" ) var index = 0 var step = 1 for (char <- s) { rows(index) += char.toString if (index == 0 ) { step = 1 } else if (index == numRows - 1 ) { step = -1 } index += step } rows.mkString } }
结果 执行用时 : 516 ms, 击败 100.00% 使用 Scala 的用户
内存消耗 : 55.05 MB, 击败 87.50% 使用 Scala 的用户
Rust 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 impl Solution { pub fn convert (s: String , num_rows: i32 ) -> String { if num_rows <= 1 || s.len () as i32 <= num_rows { return s; } let mut rows : Vec <String > = vec! [String ::new (); num_rows as usize ]; let mut index = 0 ; let mut step = 1 ; for ch in s.chars () { rows[index as usize ].push (ch); if index == 0 { step = 1 ; } else if index == num_rows - 1 { step = -1 ; } index += step; } rows.join ("" ) } }
结果 执行用时 : 0 ms, 击败 100.00% 使用 Rust 的用户
内存消耗 : 2.37 MB, 击败 9.00% 使用 Rust 的用户
Racket 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 (define (convert s num-rows) (define (make-log char row) `(log ,char ,row)) (define (log? log) (symbol=? (car log) 'log )) (define (log-char log) (cadr log)) (define (log-row log) (if (log? log) (caddr log) (error log))) (define (construct-result log-list) (define (iterator row) (if (>= row num-rows) "" (string-append (foldl (lambda (current accumulator) (string-append accumulator (string (log-char current)))) "" (filter (lambda (current) (= row (log-row current))) log-list)) (iterator (+ row 1 ))))) (iterator 0 )) (define (construct-log-list rest-string state row col) (if (null? rest-string) '() (if (symbol=? 'down state) (if (= (- num-rows 1 ) row) `(,(make-log (car rest-string) row) . ,(construct-log-list (cdr rest-string) 'up (- row 1 ) (+ col 1 ))) `(,(make-log (car rest-string) row) . ,(construct-log-list (cdr rest-string) 'down (+ row 1 ) col))) (if (= 0 row) `(,(make-log (car rest-string) row) . ,(construct-log-list (cdr rest-string) 'down (+ row 1 ) col)) `(,(make-log (car rest-string) row) . ,(construct-log-list (cdr rest-string) 'up (- row 1 ) (+ col 1 ))))))) (if (or (= 1 num-rows) (> num-rows (string-length s))) s (construct-result (construct-log-list (string->list s) 'down 0 0 ))))
结果 执行用时 : 368 ms, 击败 -% 使用 Racket 的用户
内存消耗 : 12368 MB, 击败 -% 使用 Racket 的用户
Erlang 暂时未解决
结果 执行用时 : ms, 击败 % 使用 Erlang 的用户
内存消耗 : MB, 击败 % 使用 Erlang 的用户
Elixir 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 defmodule Solution do @spec convert(s :: String .t(), num_rows :: integer) :: String .t() def convert (s, 1 ) do s end def convert (s, num_rows) when is_binary(s) and is_integer(num_rows) and num_rows > 1 do group_size = num_rows * 2 - 2 offset = gen_offset([], 0 , 0 , num_rows) |> Enum .reverse() |> List .to_tuple() ss = String .split(s, "" , trim: true ) mp = gen_map(0 , ss, offset, group_size, num_rows, %{}) len = length(ss) w = div(len, group_size) w = w * (num_rows - 1 ) r = rem(len, group_size) w = cond do r == 0 -> w r < num_rows -> w + 1 true -> w + (r - num_rows + 1 ) end gen_str_i(0 , num_rows, "" , w, mp) end defp gen_offset (offset, x, y, num_rows) do cond do y < num_rows - 1 && x == 0 -> gen_offset([{x, y} | offset], x, y + 1 , num_rows) x < num_rows - 1 -> gen_offset([{x, y} | offset], x + 1 , y - 1 , num_rows) true -> offset end end defp gen_map (_, [], _, _, _, mp), do: mp defp gen_map (step, [head | tail], offset, group_size, num_rows, mp) do r = div(step, group_size) i = rem(step, group_size) op = elem(offset, i) gen_map( step + 1 , tail, offset, group_size, num_rows, Map .put(mp, {r * (num_rows - 1 ) + elem(op, 0 ), elem(op, 1 )}, head) ) end defp gen_str_i (step, num_rows, str, w, mp) do if step <= num_rows - 1 do gen_str_i(step + 1 , num_rows, gen_str_j(0 , str, w, mp, step), w, mp) else str end end defp gen_str_j (step, str, w, mp, i) do j = step if step <= w do if Map .has_key?(mp, {j, i}) do nc = Map .get(mp, {j, i}) gen_str_j(step + 1 , str <> nc, w, mp, i) else gen_str_j(step + 1 , str, w, mp, i) end else str end end end
结果 执行用时 : 748 ms, 击败 100.00% 使用 Elixir 的用户
内存消耗 : 70.40 MB, 击败 100.00% 使用 Elixir 的用户