diff --git a/Python3/6. Zigzag Conversion.md b/Python3/6. Zigzag Conversion.md new file mode 100644 index 0000000..de8ac53 --- /dev/null +++ b/Python3/6. Zigzag Conversion.md @@ -0,0 +1,111 @@ +## Step 1. Initial Solution + +- よく観察すると下に行ってから上に戻ってくるだけとも見れる +- numRows分のリストを用意しておいて順番に入れていく +- 最後に順番に後ろにくっつけていけば行ける + +```python +class Solution: + def convert(self, s: str, numRows: int) -> str: + if numRows == 1: + return s + rows = [[] for _ in range(numRows)] + descending = True + index = 0 + row_index = 0 + while index < len(s): + if descending: + if row_index == numRows: + descending = False + row_index -= 2 + continue + rows[row_index].append(s[index]) + index += 1 + row_index += 1 + else: + if row_index == 0: + descending = True + continue + rows[row_index].append(s[index]) + index += 1 + row_index -= 1 + + zigzag_string = '' + for row in rows: + zigzag_string += ''.join(row) + return zigzag_string +``` + +### Complexity Analysis + +- 時間計算量:O(n) +- 空間計算量:O(n) + +## Step 2. Alternatives + +- もう少し上手いやり方がありそうだがあまり思いつかない +- https://github.com/tokuhirat/LeetCode/pull/60/files#diff-b770a1954146bd595658dc8a1791db788c438ab24d3b1727ec015a8991696d6dR70 + - なるほど、かなり綺麗に書けている + - directionを1,-1で定義してそれを足していくという発想は面白い + - ループの最後で行番号を増減させてから方向性の判定を行うと処理が見やすい + - "".join(c for row in row_to_letters for c in row) + - 外側にかかってgenerateできるということらしい + - 挙動を理解できていなかったので参考になった +- https://github.com/shintaro1993/arai60/pull/64/files#diff-7982c09acadc7e7c23e49111f0d36acc3994024cd122f55bebfefc94ca581bb2R140-R144 + - 一往復を一サイクルとみなして追加していく方法 + + ```python + cycle = 2 * (numRows - 1) + for i, c in enumerate(s): + position = i % cycle + row_index = min(position, cycle - position) + rows[row_index].append(c) + ``` + +- シンプルめに変形 + +```python +class Solution: + def convert(self, s: str, numRows: int) -> str: + if numRows == 1: + return s + + row_to_letters = ['' for _ in range(numRows)] + descending = True + row = 0 + for letter in s: + row_to_letters[row] += letter + if descending: + row += 1 + if row + 1 == numRows: + descending = False + else: + row -= 1 + if row == 0: + descending = True + continue + + return ''.join(row_to_letters) +``` + +## Step 3. Final Solution + +- directionを使ってみる実装 +- 理解が難しい訳ではないしこれで良さそう + +```python +class Solution: + def convert(self, s: str, numRows: int) -> str: + if numRows == 1 or len(s) <= numRows: + return s + + direction = 1 + row = 0 + row_in_letters = ['' for _ in range(numRows)] + for letter in s: + row_in_letters[row] += letter + row += direction + if row == 0 or row == numRows - 1: + direction *= -1 + return ''.join(row_in_letters) +```