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