题目描述
z字型变换
自己一开始的思考有所偏差,一直在考虑行和数的位置的关系,导致将问题复杂化,这里涉及到字符串特定的位置的字符的问题,过于复杂化了。但是还是记录一下自己的思考。以下为java代码实现。(没跑成功,,,)
package cz;
//日期:2022.01.05
//题目:z字型(回文子串---就是正着读和倒着读都是一样的)
//题解:将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
//比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
//一些收获:
public class zshape_0105 {
public static void main(String[] args) {
//输入字串
String str="PAYPALISHIRING";
String result1="PAHNAPLSIIGYIR";
String result2="PINALSIGYAHRPI";
System.out.println(convert(str, 3));
/*
* boolean if1=result1.equals(convert(str, 3));
*
* boolean if2=result2.equals(convert(str, 4)); System.out.println(if1);
* System.out.println(if2);
*/
// System.out.println(convert(str, 3));
/*如何将字符数组转化为字符串
* char[][] charArray = new char[10][10]; charArray[1][1]='7';
* charArray[1][2]='8';
*
* charArray[2][1]='5'; charArray[2][2]='6';
*/
/*
* str1 = String.valueOf(charArray[2]); System.out.println(str1); converting
* from char[] to string //验证字符串是否可以直接做相加处理 String str11="12345"; String
* str12="56789"; System.out.println(str11+str12); String str1 ="";
*/
}
private static String convert(String str, int numRows) {
// TODO Auto-generated method stub
int len=str.length();
//确定数组的列数
//根据每一行的关系来加
//先将字符串转化为数组
char [] str_temp=str.toCharArray();
//二维数组保存每一行的字符
char [][] char_target=new char [numRows][len];
//对每一行进行汇总
String [] str_target=new String [numRows] ;
String str_result="";
//每一行的个数记录
int [] stn=new int [numRows];
for(int i=0;i<numRows;i++)
{
/*
* str1=a1+a(n1*2(row-1))
* str2=a2+a(n2*2(row-2))+a(n2*(row-2)+(2(row-1)-2(row-2)))
* str3=a3+a(n3*2(row-3))+a(n3*(row-3)+(2(row-1)-2(row-3)))
* if(targetstr%row==0)
* str4=a4+a(n4*2(row-1))
*/
if(i<len)
{
//i表示行,stn表示该行的个数,此时表示第几行的第一个字符作为该行的第一个值
char_target[i][stn[i]]=str_temp[i];
stn[i]=stn[i]+1;
if(i==0||i==numRows-1)
{
int nt1=1;
while(i+nt1*2*(numRows-1)<len)
{
char_target[i][stn[i]]=str_temp[i+nt1*2*(numRows-1)];
stn[i]=stn[i]+1;
nt1=nt1+1;
}
}
else
{
for(int nt=1; i+(nt-1)*2*(numRows-1)+2*(numRows-1-i)<len;nt++)//判断条件为当前位置加上n1
{
char_target[i][stn[i]]=str_temp[i+(nt-1)*2*(numRows-1)+2*(numRows-1-i)];
stn[i]=stn[i]+1;
if(i+nt*2*(numRows-1)<len)
{
char_target[i][stn[i]]=str_temp[i+nt*2*(numRows-1)];
stn[i]=stn[i]+1;
}
}
}
str_target[i]=String.valueOf(char_target[i]);
str_result=str_result+str_target[i];
}
}
return str_result;
}
}
如果还有机会再回头优化解决的话,也有个印象吧。
目前比较正确的题解:
应该从字符串的摆放顺序来填充到各行。
如果为一行,则返回字串本身。
如果不为一行,那么遍历字符串的各个字符。首先开辟一个二维数组,用来积累每一行的字符。如果当前行为第一行,那么行数位置值增加,如果当前行为最后一行,那么行数位置值减少。
最后将各行数汇总输出便可。
以下为Java的实现代码
package cz;
//日期:2022.01.05
//题目:z字型(回文子串---就是正着读和倒着读都是一样的)
//题解:将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
//比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
//一些收获:首先是思路上的偏差,不应该考虑复杂的数学规律,而是以方向来确定存储;其次,新建字符串的时候,默认字符串的值是null,
//这会导致前缀字符为null,所以进行字符拼接时,应该考虑先将null清空。
public class zshape_0105 {
public static void main(String[] args) {
//输入字串
String str="PAYPALISHIRING";
String result1="PAHNAPLSIIGYIR";
String result2="PINALSIGYAHRPI";
System.out.println(convert(str, 3));
//替换字符串中的null值
String res =convert(str, 3).replace(Character.toString('\0'), "");
System.out.println(res);
}
private static String convert(String str, int rows) {
// TODO Auto-generated method stub
if(rows==1)
{
return str;
}
//将字符串转换为字符数组
char [] char_temp=str.toCharArray();
//创建一个二维字符数组
int c= rows > str.length()? rows : str.length();
String[] str_temp=new String [rows];
for(int i=0;i<rows;i++)
{
str_temp[i]="";
}
boolean down=false;
int p=0;
for(int i=0;i<str.length();i++)
{
if(p==0)
{
down=true;
}
if(p==rows-1)
{
down=false;
}
str_temp[p]=str_temp[p]+String.valueOf(char_temp[i]);
if(down)
{
p=p+1;
}
else
{
p=p-1;
}
}
String res="";
for(int i=0;i<rows;i++)
{
res=res+str_temp[i];
}
return res;
}
}
提交通过。但是性能不太行?
下面尝试用python语言进行实现
# This is a sample Python script.
# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
def convert(s,numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
if numRows == 1:
return s;
# 生成一维字符数组
arr = [[] for i in range(numRows)]
p = 0
for i in s:
if p == 0:
down = True
if p == numRows - 1:
down = False
arr[p].extend(i)
# 这里犯了一个错误,就是这里的i不表示下标,而是当前的字符,且这里直接做append,不用做等于
if down:
p = p + 1
else:
p = p - 1
res = []
# 不应该直接赋值为字符串,而是数组
for i in range(numRows):
res.extend(arr[i])
# res.(arr[i])
# 这里不可以直接做相加处理
# append 与extend的区别,append命令是将整个对象加在列表末尾;而extend命令是将新对象中的元素逐一加在列表的末尾
# 数组做拼接很方便,拼接完成再加到字符串中,这里我的疑惑是:为什么不可以重复做join操作?
return "".join(res)
pass
str = "PAYPALISHIRING"
print(convert(str, 3))
这里我的疑惑是,为何不可以数组与字符串做叠加处理,这也许问题的本质是数据类型的相互对应吧。
提交结果如下:
python用时比较长,但节省内存。这里有一个小插曲,就是py对于缩进的要求很严格,导致我提交的时候由于空格的原因出现了提交错误。