leetcode 05 最长相同元素之间的的最大字符串 && 06 Z形字符串排序

05 最长相同元素之间的的最大字符串
该题最开始的时候由于紧接在03题目的下面,且其给出的例子和03题十分相似,所以凭借对于03题的理解,不由的想到了其解题方法为将相同元素寻找出来并取出其中不相同元素加上最后一个相同元素的方法,以为和03题为同一种类型的题目。所以做出了以下的解题:
class Solution {
public:
    string longestPalindrome(string s) {
        string max;
        string tmp;
        if(s.size()==1)
            return s;
         vector<int> flag(256,0);
        int start=0;
        for(int i=0;i<s.length();i++){
            if(flag[s[i]]>start)
                start=flag[s[i]];
            flag[s[i]]=i;
          tmp=s.substr(start,i-start);
           for(int j=i+1;j<s.length();j++){
               int n=0;
               if(s[j]!=s[i])
                   break;
               n++;
               tmp=s.substr(i,n+2);  
           }
            if(tmp.length()>max.length())
                max=tmp;
        }
        return max;
    }
};

参考了03题中那个让人印象深刻的通过对字符串位置进行记录的方法,对于例题特例可以很好的解决,但当最后字符串为最大的时候解法就出错了,回头读了一下题目发现该思路彻底错误,该题的解题思路应该是输出两个相同元素中间的最大字符串,并非输出两个连续相同字符串间的最大字符串,正确解法:
class Solution {
public:
    string longestPalindrome(string s) {  
    if(s.empty()) return"";
        if(s.size()==1) return s;
        int min=0;
        int maxLen=1;
        for(int i=0;i<s.size();){
            if(s.size()-i<=maxLen/2)
                break;
            int j=i,k=i;
            while(k<s.size()-1 && s[k]==s[k+1])++k;
            i=k+1;
            while(k<s.size()-1 && j>0 && s[j-1]==s[k+1]){
                --j;
                ++k;
            }
            int nLen=k-j+1;
            if(nLen>maxLen){
                min=j;
                maxLen=nLen;
            }
        }
        return s.substr(min,maxLen);
    }
};

跳过相同元素,通过二分查找的方法对于字符串进行查找,并记录下最大的字符串为该题的解题方法。
06 Z形字符串排序

对于这题刚开始的时候并没有看懂,不是很明白的给出的字符串表是什么意思。于是直接看了输出结果和输入的值,并正好发现,输出字符串第一个元素和第二个元素在输入字符串相隔3个元素,第二行中每个元素在输入字符串中像个1个元素。三行依旧,于是自以为,对于单数行其间隔为nRows+1,双数行时其间隔为nRows/2+1,于是想出以下解法:
class Solution {
public:
    string convert(string s, int numRows) {
        string answer;
        if(s.empty())
        return "";
        for(int i=0;i<numRows;i++){
            if(i%2==0){
                for(;i<s.size();){
                answer.append(&s[i]);
                i=i+numRows+1;
                }  
            }
            else{
                for(;i<s.size();){
                answer.append(&s[i]);
                i=i+numRows/2+1;
                } 
            }
           
        }
       return answer;
    }
};

然而提交出错了,对应于特解可以解决问题,于是重读题目发现字符串不应该从左向右读,而是将输入字符串转为从上向下读以后,再从左向右输出,且间插为中间一行插单个元素,于是乎解题又华丽丽的出错了。但想到对于2行之类的双数行,该题没有很明确的表示到底其时什么情况,就去解答中寻找了一下,寻找到一个方便理解的,归纳法方案:
对于题目中每行元素有:

对于第一行【0,2m-2,4m-4,6m-6....】
最后一行【m-1,3m-3,5m-5】
对于中间的i行数【i,2m-2-i,2m-2+i,4m-4-i,4m-4+i...】,于是根据该规律其程序为:
class Solution {
public:
    string convert(string s, int numRows) {
        string answer;
        int i=0,j;
        if(numRows==1) return s;
        for(i=0;i<numRows;i++){
            j=0;
            while(j<s.size()+i){
                if(i<numRows-1 && i>0 && j>i)
                    answer+=s.at(j-i);
                if((i+j)<s.size())
                    answer+=s.at(j+i);
                j+=2*numRows-2;
            }
        }
        return answer;
        }
    };

对于这两题犯了相同的错误,即未认真审题,就根据所给的特例进行主观臆想,所以得出结果大多为特解,而对于一般性的,规律性的程序没给出其正确方案,审题还是很重要啊!

不得不吐槽一下,为什么CSDN的草稿删除后,会自动删除博客文章啊!不应该是拷贝一份么,发布了以后以为可以删除草稿了,结果没想到彻底删除了以后竟然连发布文章都没了。所以同一份东西写两份也真的是有点悲催。感觉要是耐性差点的朋友可能就直接删了。可能有人问为啥要保存草稿呐?我也不想啊,博客页面突然犯抽,插不进图片,本来就想两个索性一起写了,就保存了一下,刷新再来喽!结果还出了这种问题,所以让我取和谁说理去。。。。所以广大写手草稿别删哦!可能文章就直接404了。

猜你喜欢

转载自blog.csdn.net/u010404530/article/details/79456776