C语言z形变换算法,6. Z字形变换(LeetCode)——C语言

方法一:

执行用时:

76 ms,在所有 C 提交中击败了23.00%的用户

内存消耗:

6.4 MB,在所有 C 提交中击败了60.00%的用户

#include #include #include char *zStr(char *str, int numRows)

{

int k = 0;

int len = strlen(str);

if (numRows < 2) {

return str;

}

char *resStr = (char *)malloc((len + 1) * sizeof(char));

for (int row = 0; row < numRows; row++)

{

for (int i = 0; i < len; i++)

{

// 通过观察Z形字符串,可以发现以下规律:将其以2 * numRows - 2个数归为一组,每一组的下标对其这组数字个数求余

// 可得到两组结果:一组与row相等(即Z形字符串的行的下标,从0开始),一组与row的和等于numRows - 2

// 下面从第一行开始循环,将第一行符合条件的元素放置到新数组,其后每行依次进行,直到将所有元素放置到新数组

if (i % (2 * numRows - 2) == row || i % (2 * numRows - 2) == 2 * numRows - 2 - row)

{

resStr[k++] = str[i];

}

}

}

resStr[len] = '\0';

return resStr;

}

int main(void)

{

char *str = "nfgszvcsdx";

int numRows = 5;

char *retStr = zStr(str, numRows);

int i = 0;

while (retStr[i] != '\0')

{

printf("%c", retStr[i]);

i++;

}

printf("\n");

}

这个方法事件复杂度为O(numRows*n),n为字符串长度,numRows为字符串长度。

空间复杂度为O(n)。

方法二:

执行用时:

0 ms, 在所有 C 提交中击败了100.00%的用户

内存消耗:

6.6 MB, 在所有 C 提交中击败了44.94%的用户

#include #include #include char *convert(char *str, int numRows)

{

int k = 0;

int len = strlen(str);

char *resStr = (char *)malloc((len + 1) * sizeof(char));

// 特殊情况:行数小于2,或者字符串长度不大于行数,则直接返回字符串

// 因为此时要么只有一行,要么只有一列

if (numRows < 2 || len <= numRows)

{

return str;

}

for (int row = 0; row < numRows; row++)

{

// 将每一个numRows指定的行的行首字符存储到返回字符

resStr[k++] = str[row];

for (int i = row; i < len;)

{

// 在每一个numRows行,寻找原字符串中相应的元素下标

// 每行第二个元素下标与第一个元素下标具有以下关系:j = i + 2numRows - 2 - 2row

// 特殊情况:最后一行第一个和第二个元素是重合的,因此下面的表达式为: i += 0 -> i,即i没变

i += 2 * (numRows - row - 1);

// 特殊情况:最后一行第一个和第二个元素是重合的,因此,不需要计算,

// 在这里排除最后一行:numRows - row > 1

if (numRows - row > 1 && i < len) {

resStr[k++] = str[i];

}

// 每行第二个元素和第三个元素下标具有以下关系:j = i + 2row

// 特殊情况:最后一行第一个和第二个元素是重合的,因此第三个元素与第一个元素下标符合此关系

i += 2 * row;

if (row > 0 && i < len)

{

resStr[k++] = str[i];

}

}

}

resStr[k] = '\0';

return resStr;

}

int main(void)

{

char *str = "nfaskofncklasnfclas";

int numRows = 5;

char *retStr = convert(str, numRows);

int i = 0;

while (retStr[i] != '\0')

{

printf("%c", retStr[i]);

i++;

}

printf("\n");

}

此方法时间复杂度为O(n),n为字符串长度。虽然循环时嵌套的,但是最终循环的次数是n次,将n个字符全部放置到新数组。

空间复杂度为O(n),n为字符串长度。

方法三

这也是官方给出的方法,和方法二很类似。都是横向遍历Z字形字符串。

通过观察Z字形字符串,可以得出下面的性质:、

row为横向循环的行的下标,0 =< row < numRows

首行元素的下标为k(2numRows - 2) + row,k为偶数,从0开始

中间行元素的下标为k(2numRows - 2) + row,(k + 1)(2numRows - 2) - row,k为从0开始的整数。

尾行元素的下标为k(2numRows - 2) + row,k为偶数,从0开始

根据以上性质,进行横向循环,可以很容易就获得最终的字符串。

执行用时:0 ms, 在所有 C 提交中击败了100.00%的用户

内存消耗:6.5 MB, 在所有 C 提交中击败了58.46%的用户

#include #include #include char *convert (char *str, int numRows) {

int len = strlen(str);

// 必须排除非Z字形的情况

if (numRows < 2)

{

return str;

}

int k = 0;

int loopConst = 2 * numRows - 2;

char *retStr = (char *)malloc((len + 1) * sizeof(char));

for (int row = 0; row < numRows; row++) {

for (int i = 0; i + row < len; i += loopConst) {

retStr[k++] = str[i + row];

if (row != 0 && row != numRows - 1 && i + loopConst - row < len ) {

retStr[k++] = str[i + loopConst - row];

}

}

}

retStr[k] = '\0';

return retStr;

}

int main (void) {

char *str = "msd";

int numRows = 4;

char *retStr = NULL;

int i = 0;

retStr = convert(str, numRows);

while (retStr[i] != '\0')

{

printf("%c", retStr[i++]);

}

printf("\n");

}

时间复杂度: O(n)

空间复杂度: O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值