室内设计网站会员哪个值得买百度搜索收录入口
[ 题目描述 ]:
[ 思路 ]:
- 题目要求将一个字符串按照给定的行数进行 z 字形排列,然后读取每一行组成的新的字符串
- 最简单的想法就是遍历字符串,对每个字符从 0 - numRows - 0,这样的顺序去存储每个字符所在的行,然后遍历每一行放入答案数组
- 运行如下
char* convert(char* s, int numRows) {int len=strlen(s);if(len==1 || numRows==1) return s;bool is_reverse=false;int* char_index=(int*)malloc(sizeof(int)*(len));char* ans=(char*)malloc(sizeof(char)*(len+1));ans[len]='\0';int index=0;for(int i=0;i<len;i++){if(is_reverse){char_index[i]=index--;}else{char_index[i]=index++;}if(index==numRows-1 || index==0){is_reverse=!is_reverse;}}int row=0,ans_index=0;while(row<numRows){for(int i=0;i<len;i++){if(char_index[i]==row){ans[ans_index++]=s[i];}}row++;}free(char_index);return ans;
}
[ 优化 ]:
- 上面的解法使用了很多的额外空间,并且这题的重新排列的顺序是由规律的,那是否可以根据这一规律,对每行元素的位置进行确定
- 由题意可以发现,一个完整Z字形周期为 2 * numRows - 2,因为第一行和最后一行在一个完整的 z 字周期中,仅只有一个元素,其他行均为二
- 按行处理字符串, 对于每一行 i,从该行的起始位置开始
- 垂直向下的字符位于 j + i
- 斜向上的字符位于 j + cycleLen - i(首行和末行除外)
- 运行如下
char* convert(char* s, int numRows) {if (numRows==1) return s;int len=strlen(s);char* ans=(char*)malloc(len + 1);ans[len] = '\0';int index=0;int cycleLen=2 * numRows - 2;for (int i = 0; i < numRows; i++) {for (int j = 0; j + i < len; j += cycleLen) {ans[index++] = s[j + i];if (i != 0 && i != numRows - 1 && j + cycleLen - i < len) {ans[index++] = s[j + cycleLen - i];}}}return ans;
}
[ 官方题解 ]:
- 一、利用二维矩阵模拟,就是创建一个矩阵,然后将字符按照 z 字形,存放在这个二维矩阵中,再遍历这个二维矩阵的每一行,得出答案。其实和第一种解法一样,只是我存储的是每个字符的所在的行数
- 二、压缩矩阵空间,在方法一的基础上,削减了没有用上的空间。主要通过为每一行去初始化一个空列表,然后遍历字符串,将每个字符插入对应行的列表的末尾
- 三、直接构造,通过 Z 字形变换的规律来做的,就是上面优化的算法