LeetCode(6)ZigZag Conversion

把一个字符串按照“之”字形复制在矩阵中,再把结果逐行逐列输出。原理和配图在这里。看上去题目很简单,实际上有些下标相关的东西我想了很久也debug了很久才弄清楚,更吐血的事情是,提交的时候说超时了。囧,说明办法太笨。之前采用的办法是new用一个二维数组作为中间变量,存入“之”字形字符串,再扫描一遍二维数组,把最终结果输出。这样老老实实地转换,时间当然消耗得久了。换了个办法,找到原字符串的下标和转换后的字符串的下标之间的对应关系,就可以正常提交了。
我的这个算法的时间复杂度为O(N²)。还不够好。这里看到了一个时间复杂度为O(N)的算法,这个做法更透彻地发现了数学关系,找到了原串中的下标和中间变量二维数组的关系,扫描一遍二维数组,把最终结果输出。下面贴出我自己的做法。

//  
//  Solution.h
//  LeetCodeOJ_006_ZigZag_2
//
//  Created by feliciafay on 11/30/13.
//  Copyright (c) 2013 feliciafay. All rights reserved.
//

#ifndef LeetCodeOJ_006_ZigZag_2_Solution_h
#define LeetCodeOJ_006_ZigZag_2_Solution_h

#include <iostream>
#include <string>
using namespace std;


class Solution {
public:
    string convert(string s, int nRows) {
        if (s=="")
            return "";
        if(s.length()<=nRows||nRows==1)
            return s;
        string res_str="";
        long long str_len = s.length();
        int string_circle_len=2*nRows-2;
        long long row_circle_count=str_len/string_circle_len+1;//“之”字型字符串的一个变化周期
        long long row_len = row_circle_count*(nRows-1);
//        std::cout<<"str_len="<<str_len<<" ,row_circle_count="<<row_circle_count<<" ,row_len="<<row_len<<std::endl;
        for(int i =0;i<nRows;i++) {
            if(i==0||i==nRows-1){
                long long index=i;
                long long count=0;
                  while((count<row_circle_count)&&(index<str_len)){
                    res_str+=s[index];
//                    std::cout<<"_index_="<<index<<" ,string="<<res_str<<std::endl;
                    index+=string_circle_len;
                    count++;
                }
            } else {
                long long index=i;
                long long count=0;
                while((count<row_circle_count)&&(index<str_len)){
                        res_str+=s[index];
//                        std::cout<<"in_1dex="<<index<<" ,string="<<res_str<<" ,index="<<index<<" ,str_len="<<str_len<<std::endl;
                        index+=2*(nRows-1-i);
                        if(index>=str_len)
                            continue;
                        res_str+=s[index];
//                        std::cout<<"in_2dex="<<index<<" ,string="<<res_str<<" ,index="<<index<<" ,str_len="<<str_len<<std::endl;
                        index+=2*i;
                        count++;
                   
                }
            }
        }
        return res_str;
    }
};

#endif


小结

(1) 先想想能不能在数学上进行简化,再敲代码。

(2) 注意处理边界条件。就本题而言,边界条件包括了,输入的字符串, 输入字符串长度为小于nRow, 除法表达式中的分母为零。

update:  2014-12-15

class Solution {
public:
    string convert(string s, int nRows) {
        if (nRows <=1)
            return s;
        int length = s.length();
        int period = nRows * 2 - 2;
        int rest = 0;
        string result = "";
        map<int, string> convert_map;
        //for (int j = 1; j <= nRows;++j)
        //    convert_map[j] = "";
        for (int i = 0; i < length; ++ i) {
            rest = (i+1) % period;
            if (rest==0)
                convert_map[2] += s.substr(i,1);
            else if (rest > nRows)
                convert_map[nRows * 2 - rest] += s.substr(i,1);
            else
                convert_map[rest] += s.substr(i,1);
        }
        
        for (int i = 1; i <= nRows; ++i)
            result += convert_map[i];
        
        return result;
    }
};


你可能感兴趣的:(LeetCode,String)