列表

详情


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 不能含尾随空格,但它可能会有一个或者多个前置空格。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: string decodeCiphertext(string encodedText, int rows) { } };

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, " ")) // 移除末尾多余空格
}

上一题