2075. 解码斜向换位密码
字符串 originalText
使用 斜向换位密码 ,经由 行数固定 为 rows
的矩阵辅助,加密得到一个字符串 encodedText
。
originalText
先按从左上到右下的方式放置到矩阵中。
先填充蓝色单元格,接着是红色单元格,然后是黄色单元格,以此类推,直到到达 originalText
末尾。箭头指示顺序即为单元格填充顺序。所有空单元格用 ' '
进行填充。矩阵的列数需满足:用 originalText
填充之后,最右侧列 不为空 。
接着按行将字符附加到矩阵中,构造 encodedText
。
先把蓝色单元格中的字符附加到 encodedText
中,接着是红色单元格,最后是黄色单元格。箭头指示单元格访问顺序。
例如,如果 originalText = "cipher"
且 rows = 3
,那么我们可以按下述方法将其编码:
蓝色箭头标识 originalText
是如何放入矩阵中的,红色箭头标识形成 encodedText
的顺序。在上述例子中,encodedText = "ch ie pr"
。
给你编码后的字符串 encodedText
和矩阵的行数 rows
,返回源字符串 originalText
。
注意:originalText
不 含任何尾随空格 ' '
。生成的测试用例满足 仅存在一个 可能的 originalText
。
示例 1:
输入:encodedText = "ch ie pr", rows = 3 输出:"cipher" 解释:此示例与问题描述中的例子相同。
示例 2:
输入:encodedText = "iveo eed l te olc", rows = 4 输出:"i love leetcode" 解释:上图标识用于编码 originalText 的矩阵。 蓝色箭头展示如何从 encodedText 找到 originalText 。
示例 3:
输入:encodedText = "coding", rows = 1 输出:"coding" 解释:由于只有 1 行,所以 originalText 和 encodedText 是相同的。
示例 4:
输入:encodedText = " b ac", rows = 2 输出:" abc" 解释:originalText 不能含尾随空格,但它可能会有一个或者多个前置空格。
提示:
0 <= encodedText.length <= 106
encodedText
仅由小写英文字母和 ' '
组成encodedText
是对某个 不含 尾随空格的 originalText
的一个有效编码1 <= rows <= 1000
originalText
原站题解
python3 解法, 执行用时: 420 ms, 内存消耗: 26.8 MB, 提交时间: 2023-09-17 12:13:21
class Solution: def decodeCiphertext(self, encodedText: str, rows: int) -> str: cols = len(encodedText) // rows # 辅助矩阵的列数 res = [] # 遍历到的字符 for i in range(cols): # 从左至右枚举每一条路径 r = 0 c = i while r < rows and c < cols: res.append(encodedText[r*cols+c]) r += 1 c += 1 # 删去末尾空格 while res and res[-1] == ' ': res.pop() return "".join(res)
cpp 解法, 执行用时: 120 ms, 内存消耗: 38.4 MB, 提交时间: 2023-09-17 12:13:07
class Solution { public: string decodeCiphertext(string encodedText, int rows) { int cols = encodedText.size() / rows; // 辅助矩阵的列数 string res; // 遍历到的字符 for (int i = 0; i < cols; ++i){ // 从左至右枚举每一条路径 int r = 0; int c = i; while (r < rows && c < cols){ res.push_back(encodedText[r*cols+c]); ++r; ++c; } } // 删去末尾空格 while (res.size() and res.back() == ' '){ res.pop_back(); } return res; } };
java 解法, 执行用时: 27 ms, 内存消耗: 53 MB, 提交时间: 2023-09-17 12:12:50
class Solution { public String decodeCiphertext(String encodedText, int rows) { /* 模拟: 先建立一个矩阵把字母填进去,然后再通过解码的方式读取 注意: 1.可能后前导空格,但是没有尾随空格 2.可能开始解码是从(0,0)开始的 3.矩阵的列数col可以由len/encodedText计算 0 <= encodedText.length <= 1e6 时间复杂度:O(N) 空间复杂度:O(N) */ // 原位解密法 int n = encodedText.length(); int cols = n / rows; // 解密字符串并填入sb中 StringBuilder sb = new StringBuilder(); for (int j = 0; j < cols; j++) { for (int i = 0; i < rows && i + j < cols; i++) { int curIdx = i * cols + (i + j); // 逆运算出在原来字符串的位置 sb.append(encodedText.charAt(curIdx)); } } // 去掉尾随空格 int idx = sb.length() - 1; while (idx > 0 && sb.charAt(idx) == ' ') idx--; return sb.substring(0, idx + 1); } }
golang 解法, 执行用时: 24 ms, 内存消耗: 8.8 MB, 提交时间: 2023-09-17 12:12:34
func decodeCiphertext(encodedText string, rows int) string { ans := []byte{} for i, j, k, cols := 0, 0, 0, len(encodedText)/rows; k < cols; { ans = append(ans, encodedText[i*cols+j]) // 转换成在 encodedText 上的下标 i++ j++ if i == rows || j == cols { // 触及边界 k++ i, j = 0, k // 移至下一条斜向 } } return string(bytes.TrimRight(ans, " ")) // 移除末尾多余空格 }