Leetcode 6. Z 字形变换 模拟+数学推理

原题链接:Leetcode 6. Z 字形变换

在这里插入图片描述在这里插入图片描述
代码一:

class Solution {
public:
    vector<char> res[1010];
    string convert(string s, int numRows) {
        int type=1,num=1;
        for(int i=0;i<s.size();i++)
        {
            if(type==1)
            {
                if(num==numRows)
                {
                    res[num].push_back(s[i]);
                    type=2;num=(numRows-1>0)? numRows-1:1;
                }
                else 
                  res[num++].push_back(s[i]);
            }
            else if(type==2)
            {
                if(num==1)
                {
                    res[num].push_back(s[i]);
                    type=1;num=(num+1<numRows)? num+1:numRows;
                }
                else 
                  res[num--].push_back(s[i]);
            }
        }
        string ans;
        for(int i=1;i<=numRows;i++)
        {
            for(int j=0;j<res[i].size();j++)
            {
                ans+=res[i][j];
            }
        }
        return ans;
    }
};

代码二(空间优化后):

class Solution {
public:
    string convert(string s, int numRows) {
        int type=1,num=1;
        //特判
        if(numRows==1 || numRows>=int(s.size()))
             return s;
        string ans;
        vector<string> res(numRows+2);
        for(int i=0;i<s.size();i++)
        {
            res[num] += s[i];
            if(type==1)//向下
            {
                if(num==numRows)
                { type=2;num=numRows-1; }
                else 
                   num++;
            }
            else if(type==2)//向上
            {
                if(num==1)
                { type=1;num=num+1; }
                else 
                   num--;
            }
        }
        for(auto &row: res)
           ans+=row;
        return ans;
    }
};

代码三(数学推理):

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows==1 || numRows>=int(s.size())) return s;
        string news;
        for(int i=0;i<numRows;i++)
        {
            //第一行和最后一行的两个相邻位置相差的距离为:2*numRows-2
            //即一列的字符个数numRows+Z字形中斜线上字符个数numRows-2(这两条线的重合点+第二个位置本身的点)
            if(i==0 || i==numRows-1){
                int interval=2*numRows-2;
                int j=i;
                while(j<s.size()){
                    news+=s[j];
                    j+=interval;
                }
            }
            else 
            {
                //除开第一行和最后一行,其他行的相邻位置相差距离,分为两种情况
                //第一种情况:斜线上的该行位置与前一列上的该行位置的差距,left_interval
                //第一种情况:斜线上的该行位置与后一列上的该行位置的差距,interval-left_interval
                int interval=2*numRows-2;
                int left_interval=2*(numRows-i)-2;
                int right_interval=interval-left_interval; 
                int j=i;
                int cnt=0;
                while(j<s.size()){
                    news+=s[j];
                    cnt+=1;
                    if(cnt%2!=0) j+=left_interval;
                    else j+=right_interval;
                }
            }
        }
        return news;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值