N字型变换

题目:

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

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

复制代码
P   A   H   N
A P L S I I G
Y   I   R

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

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

复制代码
string convert(string s, int numRows);

示例 1:

复制代码
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

示例 2:

复制代码
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:

复制代码
输入:s = "A", numRows = 1
输出:"A"

思路:
二维矩阵模拟:

这个题主要的突破口就是对题目的理解,题目的大致意思即把一个长字符串摆成从上到下,从左到右的N字形,然后在从左到右,从上到下的重新组合成为一个新的字符串。摆成一个矩阵,必然少不了要用到二维数组,用到二维数组,我们在不清楚字符串长度的情况下,首先想到的是把二维数组大小进行动态内存分配,然后,涉及到动态内存分配,我们最重要的一点就是要得到字符串长度与构造的二维数组的行列关系,其次再往二维数组中位置一个一个去把长字符串一一对应的填进去,最后就是按照顺序把他们读取出来。

这里稍微需要注意的就是字符串长度与二维数组行列之间的关系,题目中会给出numrows,也就是给出行数,我们这里用r代替。假设我们从第一列往下摆字符,首先先向下摆r个字符,然后向右上方摆放r-2个字符,这样我们可以看作一个周期,所以一个周期t的字符数为2*r-2,同时我们一样确定了一个周期的列数为r-1,所以我们就可以得到整个列数为(n+t-1)/2*r-2 * r-1.至于为什么要加上一个周期减一,其实道理很简单,我们在除法运算中如果没有整除,会自动舍弃后面的余数,避免字符串内被舍弃字符,我们就把二维数组做大一点,但不至于大一个周期出来,这样既可以考虑到原本字符串不整除的情况,为其补全那一个周期,也可以避免多出一个空白周期出来。

代码实现:

char * convert(char * s, int numRows){
    int n=strlen(s), r=numRows;
    if(r==1||n<=r){
        return s;
    }
    int t=r*2-2;
    int c=(n+t-1)/t*(r-1);
//二维数组初始化
    char **mat=(char **)malloc(sizeof(char *)*r);
    for(int i=0;i<r;i++){
        mat[i]=(char *)malloc(sizeof(char)* c);
        memset(mat[i], 0, sizeof(char)* c);
    }
//二维数组填充
    for(int i=0, x=0, y=0; i<n; i++){
        mat[x][y]=s[i];
        if(i%t<r-1){
            x++;
        }else{
            x--;
            y++;
        }
    }
//取出字符
    int pos=0;
    for(int i=0; i<r;i++){
        for(int j=0;j<c;j++){
            if(mat[i][j]){
                s[pos++]=mat[i][j];
            }
        }
        free(mat[i]);
    }
    free(mat);
    return s;
}
相关推荐
不惑_4 分钟前
List 集合安全操作指南:避免 ConcurrentModificationException 与提升性能
数据结构·安全·list
qq_4335545412 分钟前
C++ 面向对象编程:递增重载
开发语言·c++·算法
带多刺的玫瑰33 分钟前
Leecode刷题C语言之切蛋糕的最小总开销①
java·数据结构·算法
巫师不要去魔法部乱说44 分钟前
PyCharm专项训练5 最短路径算法
python·算法·pycharm
qystca1 小时前
洛谷 P11242 碧树 C语言
数据结构·算法
冠位观测者1 小时前
【Leetcode 热题 100】124. 二叉树中的最大路径和
数据结构·算法·leetcode
XWXnb61 小时前
数据结构:链表
数据结构·链表
悲伤小伞1 小时前
C++_数据结构_详解二叉搜索树
c语言·数据结构·c++·笔记·算法
m0_675988233 小时前
Leetcode3218. 切蛋糕的最小总开销 I
c++·算法·leetcode·职场和发展
hnjzsyjyj4 小时前
“高精度算法”思想 → 大数阶乘
数据结构·高精度算法·大数阶乘