ZigZag转换 算法

题目出处

https://leetcode.com/problems/zigzag-conversion/

ZigZag转换

假设 给定一个字符串“abcdefghijk…xyz”及一个转换的行数5. 对数据进行处理。

行数













1a


j


r


z
2b

ik

qs

y

3c
h
l
p
t
x


4df

mo

uw



5e


n


v




然后把各行的数据加起来就是:“ajrzbikqsychlptxdfmouwenv”, 就可以叫做ZigZag字符串。

ZigZag转换就是把一个字符串转换为N行的ZigZag的格式。

分析


一种直观的解法就是根据上面描述的思路来处理, 后面会符上解决代码:

  1. 设定一个m行的字符串数组。
  2. 遍历字符串,把字符放到指字的字符串中去。
  3. 逐行把字符串相加得到结果

分析这方法复杂度分析:

  • 时间复杂度为O(n+m), (注, n为字符串长度, m为要转换的行数), 字符串相加操作耗时较长
  • 开始创建了字符串数组,空间复杂度为O(m)。

所以上面算法存在两个问题:进行字符串相加操作和创建数组,来增加了空间复杂度。我们要想新的办法来解决这问题


对上面的图作过引分析

   

行数              
10   8   16   24 
21  79  1517  2325 
32 6 10 14 18 22   
435  1113  1921    
54   12   20     

我们注意到每一行的数字的索引是有规律的!

第一行和最后一行中索引相差是8, 即(5-1)*2

第二行时: 1+6 = 7,  7 + 2 = 9;  9 + 6 = 15;  15 + 2 = 17. …   即在 6和2交替进行,逐个确定下一个索引的位置。  注意到 6+2 = 8, 2 = 2*1(索引值)

第三行时:2+4 = 6;  6 + 4 = 10; 10+4 = 14 …   都是4, 可以理解为 是 4 和4 交替。 注意到 4+4 = 8;   4 = 2*2(索引值)

第四行时: 3+2 = 5; 5+6=10… 在6 和2之间交替。注意到 6+2 = 8;   4 = 2*3(索引值)

这规律可进行推广到第一行和最后一行。

所以根据当前位置,可以得到下一个字符的位置信息。可直接获取。 

这算法的时间复杂度为O(n), 空间复杂度为 O(1)


算法代码

算法1: 传统解决方案

string convert(string s, int numRows) {
        if(numRows <= 1) return s;
        string tmpStr[numRows];
        int cur = 0;
        int direct = 1;
        for(int i = 0; i < s.length(); i++){
            tmpStr[cur] += s[i];
            //根据拐点调转方向
            if(cur == 0){
                direct = 1;//
            }
            else if(cur == numRows-1){
                direct = -1;
            }
            cur += direct;
        }
        string ret = "";
        for(int i = 0; i < numRows; i++){
            ret += tmpStr[i];
        }
        return ret;
    }

算法2: 按位置填空法

string convert_0(string s, int numRows) {
        if(numRows <= 1) return s; 
        string tmpStr(s.length(), '\0');
        
        int cur = 0;
        for(int n = 0; n < numRows; n++){  
            //准备移动的步数
            int move[2] = {(numRows-1)*2 - 2*n, 2*n};
            //根据第一行和最后一行数据进行调整
            if(n == 0) move[1] = (numRows-1)*2;
            if(n == numRows-1) move[0] = 2*n;
            
            int i = n; //位置过引
            int cnt = 0;
            while(i < s.length()){ 
                tmpStr[cur++] = s[i];
                i+= move[(cnt++) % 2];
            }
        } 
        return tmpStr;
    }





    原文作者:Z字形编排问题
    原文地址: https://blog.csdn.net/net_wolf_007/article/details/51699299
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞