6.Z字形变换

解法一:

暴力法,把整个图形分成最后一个图形和剩下的图形,每个图形分为第一列和剩下的列,找规律编程。

                                                

图中每一个对勾是一个图形

找bug找了好久好久,最后提交的时候还因为开的数组A的大小不合适,导致数组下边越界或者超时,试了几次竟然试出来了合适的大小…… 感觉自己真是个老实人。

这种解法其实挺不好的,下边有一个好方法。

class Solution {
public:
    string convert(string s, int numRows) {
        string sresult;
        if (s==""){
            sresult="";
            return sresult;
        }
        else if(s.length()==1){
            return s;
        }
        else if(numRows==1){
            return s;
        }
        int len=s.length(),still_left;
        int Num_of_fi=(len%(2*numRows-2)==0)?len/(2*numRows-2):len/(2*numRows-2)+1;    //图形的数量
        int k=0,left=0,right;
        char A[1000][5000];
        for(int i=0;i<numRows;i++){
    		for(int j=0;j<5000;j++){
                A[i][j]='*';
			}
		}
        for(int n1=0;n1<Num_of_fi;n1++){
            if(n1!=0){
               left=left+numRows-1;
        	}
            right=left+numRows-2;
            if(n1==Num_of_fi-1){    //最后一个图形,不一定会所有位置填满 
            	still_left= len-(2*numRows-2)*(Num_of_fi-1);   //还剩still_left个字符没放
				if(still_left<=numRows){
					int i=0; 
					while(still_left--){
						A[i++][left]=s[k++];  
					}
				}
				else{
					for(int i=0;i<numRows;i++){   //该图形的第一列
            			A[i][left]=s[k++];
            		}
            		still_left-=numRows;
            		right=left+still_left;
					for(int y1=left+1;y1<=right;y1++){  //每个图形的后几列 
            	    	int x1=left+numRows-1-y1;
            	  	  	A[x1][y1]=s[k++]; 
        			}
				}
			} 
			else{     //不是最后一个图形 
				for(int i=0;i<numRows;i++){   //每个图形的第一列
            		A[i][left]=s[k++];
            	}
            	for(int y1=left+1;y1<=right;y1++){  //每个图形的后几列 
            	    int x1=right+1-y1;
            	    A[x1][y1]=s[k++]; 
        		}
			} 
    	}
        
        int loca=0;
    	for(int i=0;i<numRows;i++){
    		for(int j=0;j<=right;j++){
                if(A[i][j]!='*'){
                     sresult+=A[i][j];
                }
			}
		}
        return sresult;
    }
};

解法二:

真是太不会变通了。题目说是Z字形,也不能真的非是Z字形啊,重点得看题目要干嘛,题目说让他按Z字形排列,最后输出的是另一个维度的排列好的顺序。所以只要有另一个维度的顺序就好。分析发现,Z字形排列,可以定义一个有numRows行的rows,每一行是一个字符串。将s中的字符按照从上往下,在从下往上,从上往下,直到所有的字符都放进rows为止,然后再从上往下遍历rows的每一行,输出就是答案。

class Solution {
public:
	string convert(string s, int numRows) {
        if (s.length()==1||s.length()==0){
            return s;
        }
        else if(numRows==1){
            return s;
        }
        vector<string> result(numRows);
        int director=-1;    //director表示当前遍历方向,1为向下,-1为向上
        int current=0;
        for(char c : s){
            result[current]+=c;
            if(current==0 || current==numRows-1){   //是第一行或者最后一行,要翻转遍历方向
                director=-director;
            }
            current+=director;
           
        }
        string output;
        for(string row :result){
            output+=row;
        }
		return output;
	}
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值