这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战
背景
学习前端三个月了,准备刷刷面试题,总结总结,一天几道面试题,向大厂进军。
“Z字形变换”在力扣的中是一个中等难度的题,不过当看完本文以后,你就会发现,中等难度的题,也不过如此!
问题
Z字形变换
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
请你实现这个将字符串进行指定行数变换的函数。
示例1:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解析
我们来看图分析一下:
思路:
1:如果只有一行,我们直接返回字符串。
- 我们分析图形,可以看到当在第0行或者(numRows-1)行的时候,Z字形的箭头方向发生改变。这个就是我们所要找的边界。
3.我们需要确定行数,我们在遍历字符串的时候,可以根据边界(0||numRow-1)来设置当前行递增,还是递减。
- 还有一个点需要注意,我们看输出的内容,是排好序的数组,一行一行读取的,不考虑数字错位问题。只需要把非垂直行的数字添加进去即可。
我们来看看代码:
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
if(numRows===1 || s.length<=1) return s;
//截取字符串转换为数组
var strArr=s.split("");
//设置初始行为0
var curRow=0;
//设置方向向下,方向控制curRow递增还是递减
var isDown=false;
//存放
var cacheArr=[];
for(var i=0;i<strArr.length;i++){
//取当前行并初始化
cacheArr[curRow]=cacheArr[curRow] || [];
//添加
cacheArr[curRow].push(strArr[i]);
//临界点,改变方向
if(curRow===0 || curRow === numRows-1){
isDown=!isDown;
}
//通过方向来判断是行数递增,还是递减。
curRow +=(isDown? 1:-1);
}
str="";
//遍历数组
for(var j=0;j<cacheArr.length;j++){
//数组转字符串
str+=cacheArr[j].join("");
}
return str;
};
验证:
代码执行效果图:
结语
一步一步慢慢来,踏踏实实把活干!