将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R E T O E S I I G E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。
领悟方法论:
1 先画出 空串,A,AB,…一般情况… 的图形
2 用笔 画线找可循环的路径
3 不符合循环的 先单独处理
4 列出所有变量画表格 找变量规律【只要有规律 就用公式拆开写出】
(注:若变量出现sb弱智错误,别浪费时间想如果是这样结果是啥样捏,纯浪费时间,主要是激起了强迫症心里!!)
1 二维数组暴力画Z形 —— 【巨慢】执行用时 :1376 ms, 在所有 Python 提交中击败了5.05% 的用户 —— 内存消耗 :18.8 MB, 在所有 Python 提交中击败了5.03%的用户
难点是 while i<n-2{while and i<n-2 while and i<n-2} 这3个一样的代码实现goto one: 的回退功能
def convert(s, numRows):
if numRows == 1:
return s
if s == '': # 因为下面右s[0][0]
return ''
n = len(s)
'''核心卡壳点:用循环三角形找出二维数组的边界'''
sum_of_one_sjx = 2*numRows -2 # 一个三角形内的字符总数
need_cols = (n // sum_of_one_sjx) * (sum_of_one_sjx // 2)
if n%sum_of_one_sjx != 0:
need_cols += sum_of_one_sjx // 2 # 直接暴力加一个单位的列数,正好放越界
'''[ [列数] 行数 ]'''
ss = [['' for _ in range(need_cols)] for _ in range(numRows)]
'''开始填充字符![预判+1走好,因为匹配当前符合的要处理超出的一个]'''
Lrow = 0 # L为local 寓意着当前行、列
Lcol = 0
ss[0][0] = s[0]
i = 1
"""重要:这句while起到 goto one:的作用 [小细节:里面while也要andi <= n-2,因为可能其他条件都符合,但i超了,,,]"""
while i <= n-1:
'''先竖向【不确定长度,用while时,就是墨迹就行了,记住了!有啥条件心虚全jb写上,先约束下标,要不必报错!】'''
while Lrow+1<numRows and Lcol<need_cols and i<=n-1 and ss[Lrow+1][Lcol]=='':
Lrow += 1
ss[Lrow][Lcol] = s[i]
i += 1
'''再右上'''
while Lrow-1>=0 and Lcol+1<need_cols and i<=n-1 and ss[Lrow-1][Lcol+1]=='':
Lrow -= 1
Lcol += 1
ss[Lrow][Lcol] = s[i]
i += 1
# for tmp in ss:
# print(tmp)
'''一行行输出 [注:一个空的都不能少,因为你终止后面可能还一大堆!]'''
ans = ''
for r in range(numRows):
for c in range(need_cols):
if ss[r][c] != '':
ans += ss[r][c]
return ans
2 机智的 3个字符串栈 模拟z形行出 ———— 时间复杂度一样为On^2,但中间无空挡的无效元素,速度竟然变快至80ms
技巧领悟总结: 1 col<len(ss[row]) 2 z o字形的题:3while 配合 预先+1判断 3 ss[[''列数] 行数] 配合 ss[row].append 模拟出动态的cow行数个list 4 while的二维数组越界[][],神器用len() eg.col<len(ss[row])
def convert(s, numRows):
'''不是实先就能看出来的,是自己测试瞎试+看力扣提示样例 才改出来的- - '''
if s =='' or len(s) == 1 or numRows==1:
return s
'''
总结:
1 col<len(ss[row])
2 z o字形的题:3while 配合 预先+1判断
3 ss[[''列数] 行数] 配合 ss[row].append 模拟出动态的cow行数个list
4 while的二维数组越界[][],神器用len() eg.col<len(ss[row])
'''
n = len(s)
'''mh自创:巧用二维数组创n个list[] 【注意: 最后要把无用的''去掉】'''
ss = [['' for _ in range(1)] for _ in range(numRows)]
# for i in range(n):
'''不确定因素太大,用while 不用for'''
localRow = -1 # 注意是到numsRow - 1
i = 0
while i < n:
'''竖直向下【用+1预判好,不用单独再出来while结束超的一个】'''
while localRow + 1 < numRows and i < n:
localRow += 1
ss[localRow].append(s[i])
i += 1
'''漏下来了 该右上了【为什么=0 看ms图的循环路径!】'''
while localRow - 1 >= 0 and i < n:
localRow -= 1
ss[localRow].append(s[i])
i += 1
# for tmp in ss:
# print(tmp)
ans_str = ''
'''行定用for,列不确定用while'''
for row in range(numRows):
col = 1 # 我忽略:应该从1起 要不while直接终止了,,
while col<len(ss[row]) and ss[row][col] is not None:
ans_str += ss[row][col]
col += 1
return ans_str