把一个字符串按照“之”字形复制在矩阵中,再把结果逐行逐列输出。原理和配图在这里。看上去题目很简单,实际上有些下标相关的东西我想了很久也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; } };