Leetcode 6 Z字形变换

题目描述

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

示例图片

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

来源:力扣(LeetCode)题目链接
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解1

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1) return s;
        unordered_map<int, string> hash;
        int len = s.length();
        string finals = "";
        int p = (numRows - 1) << 1;
        for(int i = 0; i < len; i++){
            int r = i % p;
            if(r < numRows){
                 hash[r] += s[i];
            }else{
            //找找关系即可
                hash[(p-r)] += s[i];
            }  
        }
        for(int i = 0; i < numRows; i++){
            finals += hash[i];
        }
        return finals;
    }
};

提交结果

题解2(只用了个min,提高了点速度)

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1) return s;
        unordered_map<int, string> hash;
        int len = s.length();
        string finals = "";
        int p = (numRows - 1) << 1;
        for(int i = 0; i < len; i++){
            int r = i % p;
            //和题解1比较,其实我们需要选的是r和p-r中小的那个
            hash[min(r,p-r)] += s[i];
        }
        for(int i = 0; i < numRows; i++){
            finals += hash[i];
        }
        return finals;
    }
};

提交结果

题解3(按行读)

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1) return s;
        int len = s.length();
        string finals = "";
        int p = (numRows - 1) << 1;
        for(int i = 0; i < numRows; i++){
           for(int j = 0; j+i < len; j+=p){
               finals += s[i+j];
               //可以找规律,发现不规则的之间差了 p-i
               if(i != 0 && i != numRows-1 && j+p-i < len)
                    finals += s[j+p-i];
           }
        }
       
        return finals;
    }
};

提交结果

题解4(暴力)

class Solution {
public:
    string convert(string s, int numRows) {
        string newstring[numRows];
        string final = "";
        if(numRows == 1) return s;
        // 处理第一行和最后一行
        for(int i = 0; i < s.size() ; i += 2*(numRows-1)){
            newstring[0] += s[i];
        }
        for(int i = numRows-1; i < s.size(); i += 2*(numRows-1)){
            newstring[numRows-1] +=s[i];
        }
        // 处理中间
        if(numRows > 2){
            for(int i = 2; i < numRows; i++){
                int downside = 2*(numRows-i);
                int upside = 2*(i-1);
                for(int j = i-1; j < s.size();){
                    newstring[i-1] += s[j];
                    if(j + downside < s.size()){
                        newstring[i-1] += s[j+downside];
                        j += downside;
                    }else break;
                    if(j + upside < s.size())
                        j += upside;
                    else break;
                }
            }
        }
        
        for(auto i : newstring){
            final += i;
        }
        return final;
    }
};

在这里插入图片描述

题解5 flag解法

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows < 2) return s;
        string final[numRows];
        string a = "";
        int i{0}, flag{-1};
        for(auto c : s){
            final[i] += c;
            if(i == numRows-1 || i == 0) flag = -flag;
            i += flag;
        }
        for(auto c : final){
            a += c;
        }
        return a;
    }
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值