小Y学算法⚡️每日LeetCode打卡⚡️——6. Z 字形变换
Posted 呆呆敲代码的小Y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小Y学算法⚡️每日LeetCode打卡⚡️——6. Z 字形变换相关的知识,希望对你有一定的参考价值。
📢前言
- 🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
- 🌲 每天打卡一道算法题,既是一个学习过程,又是一个分享的过程😜
- 🌲 提示:本专栏解题 编程语言一律使用 C# 和 Java 两种进行解题
- 🌲 要保持一个每天都在学习的状态,让我们一起努力成为算法大神吧🧐!
- 🌲 今天是力扣算法题持续打卡第6天🎈!
- 🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻🌻
🌲原题样例
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"
示例 2:
输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P I N
A L S I G
Y A H R
P I
示例 3:
输入:s = "A", numRows = 1
输出:"A"
提示:
- 1 <= s.length <= 1000
- s 由英文字母(小写和大写)、’,’ 和 ‘.’ 组成
- 1 <= numRows <= 1000
🌻C#方法:按行排序法
解题思路
找规律:
numRows>=3 时
第一行 和 最后一行 的 每个下标 差为 diff = 4 +(numRows -3)2;
每行行头下标为第r行
除第一行 和 最后一行外, 每一组 应为两个数
除第一行 和 最后一行外, 每个组的第一个数 是与第一行对齐的,下标差也是diff
而每组中第二个数与第一个数的下标差为 j = diff - 2r ,因为行数每增加一行, 每一个垂直列下方会增加一个数, 每一个斜向上会增加一个数
public class Solution {
public string Convert(string s, int numRows) {
if (string.IsNullOrEmpty(s))
return "";
if (s.Length == 1)
return s[0].ToString();
if (numRows == 1)
return s;
int index = 0;
char[] result = new char[s.Length];
if (numRows == 2)
{
int halfLen = s.Length % 2 ==0? s.Length / 2 :s.Length /2 +1;
for (int i = 0, j = 1; i < s.Length;)
{
if (i < s.Length){
result[index] = s[i];
}
if (j < s.Length&&index+halfLen<s.Length){
result[index+halfLen] = s[j];
}
index++;
i += 2;
j += 2;
}
return new string(result);
}
int diff = 4 + (numRows - 3) * 2;
int r = 0;
while (r < numRows)
{
if (r == 0 || r == numRows - 1)
{
for (int k = r; k < s.Length; k += diff)
{
result[index++] = s[k];
}
}
else
{
int j = diff - 2 * r;
for (int k = r; k < s.Length; k += diff)
{
result[index++] = s[k];
if (k + j < s.Length)
result[index++] = s[k + j];
}
}
r++;
}
return new string(result);
}
}
链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/zxing-bian-huan-cjie-fa-80ms-shi-jian-10-ebr2/
执行结果
执行结果 通过,执行用时92ms,内存消耗 26.6MB
🌻Java 方法:按行排序
思路
通过从左向右迭代字符串,我们可以轻松地确定字符位于 Z 字形图案中的哪一行。
算法
我们可以使用 \\text{min}( \\text{numRows}, \\text{len}(s))min(numRows,len(s)) 个列表来表示 Z 字形图案中的非空行。
从左到右迭代 ss,将每个字符添加到合适的行。可以使用当前行和当前方向这两个变量对合适的行进行跟踪。
只有当我们向上移动到最上面的行或向下移动到最下面的行时,当前方向才会发生改变。
class Solution {
public String convert(String s, int numRows) {
if (numRows == 1) return s;
List<StringBuilder> rows = new ArrayList<>();
for (int i = 0; i < Math.min(numRows, s.length()); i++)
rows.add(new StringBuilder());
int curRow = 0;
boolean goingDown = false;
for (char c : s.toCharArray()) {
rows.get(curRow).append(c);
if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
curRow += goingDown ? 1 : -1;
}
StringBuilder ret = new StringBuilder();
for (StringBuilder row : rows) ret.append(row);
return ret.toString();
}
}
链接:https://leetcode-cn.com/problems/zigzag-conversion/solution/z-zi-xing-bian-huan-by-leetcode/
执行结果
执行结果 通过,执行用时6ms,内存消耗 38.8MB
复杂度分析
时间复杂度:O(n)
空间复杂度:O(n)
💬总结
- 今天是力扣算法题打卡的第六天!今天的题有点难,借助力扣大神题解看了半天!
- 文章采用 C# 和 Java 两种编程语言进行解题
- 一些方法也是参考力扣大神写的,也是边学习边分享,再次感谢算法大佬们
- 那今天的算法题分享到此结束啦,明天再见!
以上是关于小Y学算法⚡️每日LeetCode打卡⚡️——6. Z 字形变换的主要内容,如果未能解决你的问题,请参考以下文章
小Y学算法⚡️每日LeetCode打卡⚡️——16.搜索插入位置
小Y学算法⚡️每日LeetCode打卡⚡️——20.二进制求和