Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leetcode 006. Z 字形变换 #102

Open
meibin08 opened this issue Nov 17, 2020 · 0 comments
Open

Leetcode 006. Z 字形变换 #102

meibin08 opened this issue Nov 17, 2020 · 0 comments
Labels
LeetCode 备战技术面试,学习力扣海量技术面试题,一起助你提升编程技能,轻松拿下世界 IT 名企 Dream Offer 中等 LeetCode题目的等级区分 - 中等 字符串 LeetCode题目的标签分类 - 字符串

Comments

@meibin08
Copy link
Owner

题目描述:

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

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

L   C   I   R
E T O E S I I G
E   D   H   N

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

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

string convert(string s, int numRows);

示例1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

示例2:

输入: s = "LEETCODEISHIRING", numRows =4
输出:"LDREOEIIECIHNTSG"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

难度:

  • 难度:中等
  • 支持语言:JavaScriptJavaPython

相关标签

相关企业

  • 阿里
  • 腾讯
  • 微保
  • 有赞

思路 1:

  • 通过从左向右迭代字符串,我们可以轻松地确定字符位于 Z 字形图案中的哪一行,

  • 我们可以使用 min(numRows,len(s)) 个列表来表示 Z 字形图案中的非空行。

  • 从左到右迭代 ss,将每个字符添加到合适的行。可以使用当前行和当前方向这两个变量对合适的行进行跟踪。

  • 只有当我们向上移动到最上面的行或向下移动到最下面的行时,当前方向才会发生改变。

  • 算法流程: 按顺序遍历字符串 s;

    1. res[i] += c: 把每个字符 c 填入对应行 s i
    2. i += flag: 更新当前字符 c 对应的行索引;
    3. flag = - flag: 在达到 ZZ 字形转折点时,执行反向。

思路 2:

  • 整体的思路是遍历字符串,遍历过程中将每行都看成新的字符串构成字符串数组,最后再将该数组拼接起来即可
  • 如果 numRows=1 则说明当前字符串即为结果,直接返回
  • 否则整个字符串需要经历,向下向右,向下向右,这样的反复循环过程,设定 downdown 变量表示是否向下,loc 变量表示当前字符串数组的下标
  • 如果 downdown 为 true,则 loc+=1,字符串数组下标向后移动,将当前字符加入当前字符串中
  • 如果 downdown 为 false,则表示向右,则 loc−=1,字符串数组下标向前移动,将当前字符加入当前字符串中

思路 3:

  • 定义一个rows,它的作用是用来保存每一行的字母,根据题目,可以很轻松的得出第一个字母就在第1行,第二个字母在第2行...第N个字母在第numsRow行;
  • 然后开始往上,第N+1个字母在numsRow-1行...
  • 因此遍历s,并且将每一个字母添加到对应的行中,最后在将每一行字母合并就是结果。

复杂度分析

  • 时间复杂度 O(N)O(N) :遍历一遍字符串 s;
  • 空间复杂度 O(N)O(N) :各行字符串共占用 O(N)O(N) 额外空间。

代码

JavaScript 实现

/**
 * @来源: Javascript中文网 - 前端进阶资源教程 https://www.javascriptc.com/
 * @介绍:一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
 * @param {string} s
 * @param {number} numRows
 * @return {string}
 */
var convert = function(s, numRows) {
  if(numRows===1)return s
  let rows={}
  for(let i=0;i<numRows;i++){
    rows[i]=[]
  }
  let curRow=0,direction=1
  for(let i=0;i<s.length;i++){
    rows[curRow].push(s[i])
    curRow+=direction
    if(curRow===numRows || curRow===-1){
      direction*=-1
      curRow+=2*direction
    }
  }
  // console.log(rows)
  let res=''
  for(let i=0;i<numRows;i++){
    res+=rows[i].join('')
  }
  return res
};
/**
*  @作者:guanpengchn
*  @链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/hua-jie-suan-fa-6-z-zi-xing-bian-huan-by-guanpengc/

 * @param {string} s
 * @param {number} numRows
 * @return {string}
 */
var convert = function(s, numRows) {
    if(numRows == 1)
        return s;

    const len = Math.min(s.length, numRows);
    const rows = [];
    for(let i = 0; i< len; i++) rows[i] = "";
    let loc = 0;
    let down = false;

    for(const c of s) {
        rows[loc] += c;
        if(loc == 0 || loc == numRows - 1)
            down = !down;
        loc += down ? 1 : -1;
    }

    let ans = "";
    for(const row of rows) {
        ans += row;
    }
    return ans;
};

Java 实现

/**
*  @作者:guanpengchn
*  @链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/hua-jie-suan-fa-6-z-zi-xing-bian-huan-by-guanpengc/
 */
class Solution {
    public String convert(String s, int numRows) {
        if(numRows == 1)
            return s;

        int len = Math.min(s.length(), numRows);
        String []rows = new String[len];
        for(int i = 0; i< len; i++) rows[i] = "";
        int loc = 0;
        boolean down = false;

        for(int i=0;i<s.length();i++) {
            rows[loc] += s.substring(i,i+1);
            if(loc == 0 || loc == numRows - 1)
                down = !down;
            loc += down ? 1 : -1;
        }

        String ans = "";
        for(String row : rows) {
            ans += row;
        }
        return ans;
    }
}
/**
*  @作者:guanpengchn
*  @链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/hua-jie-suan-fa-6-z-zi-xing-bian-huan-by-guanpengc/

 */
class Solution {
    public String convert(String s, int numRows) {
        if(numRows == 1)
            return s;

        int len = Math.min(s.length(), numRows);
        String []rows = new String[len];
        for(int i = 0; i< len; i++) rows[i] = "";
        int loc = 0;
        boolean down = false;

        for(int i=0;i<s.length();i++) {
            rows[loc] += s.substring(i,i+1);
            if(loc == 0 || loc == numRows - 1)
                down = !down;
            loc += down ? 1 : -1;
        }

        String ans = "";
        for(String row : rows) {
            ans += row;
        }
        return ans;
    }
}
/**
*  @作者:jyd
*  @链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/zzi-xing-bian-huan-by-jyd/
 */
class Solution {
    public String convert(String s, int numRows) {
        if(numRows < 2) return s;
        List<StringBuilder> rows = new ArrayList<StringBuilder>();
        for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());
        int i = 0, flag = -1;
        for(char c : s.toCharArray()) {
            rows.get(i).append(c);
            if(i == 0 || i == numRows -1) flag = - flag;
            i += flag;
        }
        StringBuilder res = new StringBuilder();
        for(StringBuilder row : rows) res.append(row);
        return res.toString();
    }
}

Python 实现

# 作者:powcai
# 链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/mo-ni-guo-cheng-he-zhao-gui-lu-by-powcai/
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if not s:
            return ""
        if numRows == 1:return s
        s_Rows = [""] * numRows
        i  = 0
        n = len(s)
        while i < n:
            for j in range(numRows):
                if i < n:
                    s_Rows[j] += s[i]
                    i += 1
            for j in range(numRows-2,0,-1):
                if i < n:
                    s_Rows[j] += s[i]
                    i += 1
        return "".join(s_Rows)
# 作者:yun-yu-chen
# 链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/shu-xue-gui-lu-fa-hashfa-cpythonjavashi-xian-by-yu/
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows==1:
            return s
        ans=""
        n=len(s)
        for i in range(numRows):
            k=i
            while k<n:
                ans+=s[k]
                k+=2*(numRows-1)
                if i!=0 and i!=numRows-1 and k-2*i <n:
                    ans+=s[k-2*i]
        return ans
# 作者:zoffer
# 链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/ji-jian-jie-fa-by-ijzqardmbd/

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows == 1: return s
        rows = [""] * numRows
        n = 2 * numRows - 2
        for i, char in enumerate(s):
            x = i % n
            rows[min(x, n - x)] += char
        return "".join(rows)

其他

领略前端技术前沿,阅读IT平头哥联盟

@meibin08 meibin08 added 中等 LeetCode题目的等级区分 - 中等 字符串 LeetCode题目的标签分类 - 字符串 LeetCode 备战技术面试,学习力扣海量技术面试题,一起助你提升编程技能,轻松拿下世界 IT 名企 Dream Offer labels Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LeetCode 备战技术面试,学习力扣海量技术面试题,一起助你提升编程技能,轻松拿下世界 IT 名企 Dream Offer 中等 LeetCode题目的等级区分 - 中等 字符串 LeetCode题目的标签分类 - 字符串
Projects
None yet
Development

No branches or pull requests

1 participant