LeetCode-6.Z 字形变换 - 消费补偿算法

简介: 题目将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。示例:输入: s = “LEETCODEISHIRING”, numRows = 3输出: “LCIRETOESIIGEDHN”

解决这题的关键是找到每一行的字符位置规律,根据分析可以知道:
第一行和最后一行的字符位置相差 2*numRows-2,如下图所示:

2020091421520727.png

而对于其他行来说,字符位置加4会略过当前行的一个字符。如下图所示:

202009142155307.png

先定义一个money作为这个跨度,即int money = 2*numRows-2;,定义 j 为要访问的s字符串的字符下标。

然后,我打算对当前行做一个"补偿",即让他倒退2个位置。即j = j + money - (2*i - 2):,这样一来,T的位置就可以在E的基础上算出来(j=1, money=4): 1+4-(2*2-2)=3。

你可以理解为原来我要消费money块钱,现在我补偿回一些钱给你。那么在下次消费时,就要恰好把money消费完。即:money -= money - (2*i - 2),即money=4-(2*2-2)=2,这样就可以访问到O字符了。

这个算法,我称之为消费补偿算法,还没有看题解,不知道其他大佬的思想是不是类似。下面贴我的代码:

#include <iostream>
#include <string>
using namespace std;

/**
 * LeetCode
 * 6. Z 字形变换
 * https://space.bilibili.com/54183978
 */

class Solution {
public:
    string convert(string s, int numRows) {
         int size = s.size();
         string ans = "";

         if(numRows == 1){
             return s;
         }

         for(int i = 1; i <= numRows; i++){
             // 加第i行字符
             int j = i - 1;
             // 每行第一个字符
             ans += s[j];
             int money = 2*numRows-2;

             while(j < size){

                 if(money == 2*numRows-2 && i!=numRows){
                     // 消费补偿
                     j = j + money - (2*i - 2);
                     if(j >= size){
                         break;
                     }
                     ans += s[j];
                     money -= money - (2*i - 2);
                 } else{
                     // 消费剩余
                     j = j + money;
                     if(j >= size){
                         break;
                     }
                     ans += s[j];
                     money = 0;
                 }

                 if(money == 0){
                     money = 2*numRows-2;
                 }
             }
         }
         return ans;
    }
};

int main(){
    Solution solution;
    cout << solution.convert("LEETCODEISHIRING", 3);
}

20200914220619159.png.jpeg

目录
相关文章
|
3月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
48 0
|
2月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
3月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
35 2
|
5月前
|
算法
测试工程师的技能升级:LeetCode算法挑战与职业成长
这篇文章通过作者亲身体验LeetCode算法题的过程,探讨了测试工程师学习算法的重要性,并强调了算法技能对于测试职业成长的必要性。
85 1
测试工程师的技能升级:LeetCode算法挑战与职业成长
|
5月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
59 6
|
5月前
|
存储 算法 Java
LeetCode经典算法题:打家劫舍java详解
LeetCode经典算法题:打家劫舍java详解
80 2
|
5月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
56 1
|
5月前
|
存储 算法 Java
LeetCode经典算法题:预测赢家+香槟塔java解法
LeetCode经典算法题:预测赢家+香槟塔java解法
72 1
|
5月前
|
算法
基于小波变换的图像自适应增强算法
基于小波变换的图像自适应增强算法
26 0
|
5月前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
84 0