LeetCode 6 Zigzag Conversion (Tag:Hash Table Difficulty:Medium)

149 阅读2分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

前言

关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!

题目描述

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

image.png 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);  

示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"

示例 2:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"

示例 3:
输入:s = "A", numRows = 1
输出:"A"

链接:leetcode-cn.com/problems/zi…

题解

这道题题意是将一个字符串按照 z 字形排列,排列后按每行字符依次输出。做法就是模拟这个 z 字形的过程。

用一个数组 res 来表示转变后的字符串数组,res 每个元素为转变后每行对应的字符串,比如 res[0] 代表转变后第 0 行的字符串,对应题目的话,res[0] = 'PAHN', res[1] = 'APLSIIG', res[2] = 'YIR'。 初始时,每个字符串都为 '',我们需要将其填充。

如何填充呢?观察转变后的数组可以发现,当按照 z 字形遍历时,行号是从 0 递增到最大,然后再从最大递减到 0, 我们可以用一个方向变量来表示,当达到最大或者最小时,变换方向变量的正负。

具体实现如下,时间复杂度 O(n)

/**
 * @param {string} s
 * @param {number} numRows
 * @return {string}
 */
var convert = function(s, numRows) {
  if (numRows <= 1) return s
  let res = new Array(numRows).fill('')
  let indexDir = -1 // 方向变量
  let index = 0
  for (let i = 0; i < s.length; i++) {
      res[index] += s[i]
      // 转变方向
      if (index === numRows -1 || index === 0)  {
          indexDir = -indexDir
      }
      index += indexDir
  }
  
  let ans = ''
  for (let i = 0; i < numRows; i++) {
      ans += res[i]
  }
  return ans 
};