C#版[击败100.00%的提交] - Leetcode 6. Z字形变换 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址
http://blog.csdn.net/lzuacm。
C#版 - Leetcode 6. Z字形变换 - 题解
Leetcode 6. ZigZag Conversion
在线提交: https://leetcode-cn.com/problems/zigzag-conversion/
题目描述
将字符串 “PAYPALISHIRING”以Z字形(Zigzag pattern)排列成给定的行数:
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
● Difficulty: | Medium |
Total Accepted: 216.3K
Total Submissions: 779.4K
相关话题 字符串
分析:
<”PAYPALISHIRING”, 3> 的返回结果中的各字符在原字符串中的位置(下标index)具体如下:
- s[0],s[4],s[8],s[12] // 第1行,间隔为4 = 2⋅(3−1)" role="presentation">2⋅(3−1)2⋅(3−1)
- s[1],s[3],s[5],s[7],s[9],s[11],s[13] // 第2行,间隔为2/2
- s[2],s[6],s[10] // 第3行,间隔为4
numRows=4时,所返回的字符串中各字符原来的index的规律为:
第1行,间隔为6 = 2⋅(4−1)" role="presentation">2⋅(4−1)2⋅(4−1)
第2行,间隔为4/2交替
第3行,间隔为2/4交替
第4行,间隔为6
当numRows=5时,所返回的字符串中各字符原来的index规律为:
第1行,间隔为8 = 2⋅(5−1)" role="presentation">2⋅(5−1)2⋅(5−1)
第2行,间隔为6/2交替
第3行,间隔为4/4
第4行,间隔为2/6交替
第5行,间隔为8
如果觉得不够直观,可以看看另一个例子<”THISPROBLEMISAWESOME”, 4>(位置重排):
根据重排的图,有一种较直观的思路:
用一个字符串str来存储每一行中字符拼接成的字符串,最后将每行得到的字符串拼接到一起即为所求结果。另外,用bool值down表示方向 - 先下后上将其记为true,否则记为false。
using System;
using System.Text;
namespace Leetcode6_Zigzag
{
public class Solution
{
public string Convert(string s, int numRows)
{
StringBuilder sb = new StringBuilder();
// base case
if (s.Length == 0 || numRows <= 1)
return s;
// handle first row
for (int i = 0; i < s.Length; i += (numRows - 1) * 2)
sb.Append(s[i]);
// handle middle rows
for (int j = 1; j < numRows - 1; j++)
{
bool down = true;
for (int i = j; i < s.Length;) // Since the step has two possible values, so not add increase logic here.
{
sb.Append(s[i]); // Add first element of current row, then add others
if (down) // going down
i += (numRows - 1 - j) * 2;
else // going up
i += 2*j;
down = !down; // switch direction
}
}
// handle last row
for (int i = numRows - 1; i < s.Length; i += (numRows - 1) * 2)
sb.Append(s[i]);
return sb.ToString();
}
}
class Program
{
static void Main(string[] args)
{
Solution sol = new Solution();
String str = "PAYPALISHIRING";
int numRows = 4;
var res = sol.Convert(str, numRows);
Console.WriteLine(res);
}
}
}
不过此方法的需要另外考虑方向,并对首末两行进行特殊处理(运行时间: 112 ms),我们可以考虑找更优的解法。
如果要找到更通用的下标 Index 的规律,可用下图来表示 ,分析知从蓝色格子走到绿色格子,需要 2⋅[(n−1)−(2)]" role="presentation">2⋅[(n−1)−(2)]2⋅[(n−1)−(2)]步,而从绿色格子到红色格子需要的步数是 2⋅(2)" role="presentation">2⋅(2)2⋅(2):
观察可知,假设目前在第 k行,则该行的字符在原字符串中的数字下标依次为:
- k" role="presentation">kk
- k+2⋅(n−1−k)" role="presentation">k+2⋅(n−1−k)k+2⋅(n−1−k)
- k+2⋅(n−1−k)+2⋅k" role="presentation">k+2⋅(n−1−k)+2⋅kk+2⋅(n−1−k)+2⋅k
- k+2⋅(n−1−k)+2⋅k+2⋅(n−1−k)" role="presentation">k+2⋅(n−1−k)+2⋅k+2⋅(n−1−k)k+2⋅(n−1−k)+2⋅k+2⋅(n−1−k)
- k+2⋅(n−1−k)+2⋅k+2⋅(n−1−k)+2⋅k" role="presentation">k+2⋅(n−1−k)+2⋅k+2⋅(n−1−k)+2⋅kk+2⋅(n−1−k)+2⋅k+2⋅(n−1−k)+2⋅k
- …
因此,通用的规律如下:
- 当numRows=1或原字符串长度为0时,直接返回原字符串s即可,因为此时无需展开。
- 第k行的第一个字符在原字符串中的index就是k。
- 第1行和最后1行的间隔相等,都是整个过程中最大的,取名为maxGap,其值为2⋅" role="presentation">⋅⋅numRow-2。
- 中间的行相邻两个index的间隔数有2个,互相交替,但其和为maxGap(也可将maxGap看作每一行的周期),分别取名为gap1和gap2。对于第k行,gap1 = maxGap-2⋅k" role="presentation">2⋅k2⋅k = 2 ⋅" role="presentation">⋅⋅ (numRows - 1 - k),gap2 = maxGap-gap1 = 2⋅k" role="presentation">2⋅k2⋅k。
已AC的代码:
using System;
namespace LeetCode_6ZigZagConversion
{
public class Solution
{
public string Convert(string s, int numRows)
{
char[] res = new char[s.Length];
// string res = new string(' ', s.Length);
if (s.Length == 0 || numRows <= 1)
return s;
int pos = 0;
for (int i = 0; i < numRows; i++)
{
int gap1 = 2 * (numRows - 1 - i);
int gap2 = 2 * i;
int index = i;
while (pos < s.Length)
{
if (gap1 > 0)
{
if (index >= s.Length)
break;
res[pos++] = s[index]; // Add char row by row
index += gap1;
}
if (gap2 > 0)
{
if (index >= s.Length)
break;
res[pos++] = s[index];
index += gap2;
}
}
}
return new string(res);
}
}
// Testing below
class Program
{
static void Main(string[] args)
{
Solution sol = new Solution();
string res = sol.Convert("PAYPALISHIRING", 3);
Console.WriteLine(res);
}
}
}
此方法不需记录方向,只需保证gap1在自减和gap2在自增的过程中均>0即可,且不需对首尾两行进行特殊处理。
Rank:
运行时间: 102 ms.
You are here!
Your runtime beats 100.00% of csharp submissions.
C#版[击败100.00%的提交] - Leetcode 6. Z字形变换 - 题解的更多相关文章
- C#版(击败100.00%的提交) - Leetcode 151. 翻转字符串里的单词 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- C#版(击败100.00%的提交) - Leetcode 744. 寻找比目标字母大的最小字母 - 题解
C#版 - Leetcode 744. 寻找比目标字母大的最小字母 - 题解 744.Find Smallest Letter Greater Than Target 在线提交: https://le ...
- C#版(击败100.00%的提交) - Leetcode 372. 超级次方 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. Leetcod ...
- Java实现 LeetCode 6 Z字形变换
6. Z 字形变换 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: L ...
- C#版[击败99.69%的提交] - Leetcode 242. 有效的同构异形词 - 题解
C#版 - Leetcode 242. 有效的同构异形词 - 题解 Leetcode 242.Valid Anagram 在线提交: https://leetcode.com/problems/val ...
- C#版(击败97.76%的提交) - Leetcode 557. 反转字符串中的单词 III - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. Leetcod ...
- [LeetCode] 6. Z 字形变换
题目链接:(https://leetcode-cn.com/problems/zigzag-conversion/) 题目描述: 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列 ...
- LeetCode 6. Z字形变换(ZigZag Conversion)
题目描述 将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数: P A H N A P L S I I G Y I R 之后从左往右,逐行读取字符:"P ...
- Leetcode(6)Z字形变换
Leetcode(6)Z字形变换 [题目表述]: 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列. 比如输入字符串为 "LEETCODEISHIRING" ...
随机推荐
- Win10 教育版
Windows 10 版本 1607 引入了专为 K-12 机构的特有需求而设计的两个版本:Windows 10 专业教育版和 Windows 10 教育版. 这些版本为不断发展的 K-12 教育 I ...
- 爬虫之selenium和PhantomJS
---恢复内容开始--- selenium selenium是什么? 是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作 环境搭建 .安装: pip instal ...
- Windows 2003 防火墙开启后无法访问FTP解决办法
最近遇到一个比较郁闷的问题,服务器开启防火墙后电脑就无法访问服务器的防火墙,但是防火墙又不能关,在例外中添加端口21也不管用. 后来在网上终于找到了一个解决方案,可以在不关掉防火墙的情况下访问服务器的 ...
- Do Now 一个让你静心学习的APP——团队博客
Do Now 一个让你静心学习的APP 来自油条只要半根团队的智慧凝聚的产物! 团队博客总目录: 团队作业第一周 团队作业第二周 Do Now -- 团队冲刺博客一 Do-Now-团队Scrum 冲刺 ...
- [转]Unity-移动设备可用的压缩解压缩源码
原文:http://www.manew.com/thread-103250-1-1.html 最近在做客户端数据的分离,不希望对项目有什么影响,也不太想用AssetBundle,太麻烦,就在网上找了找 ...
- Spring Cloud下微服务权限方案
背景从传统的单体应用转型Spring Cloud的朋友都在问我,Spring Cloud下的微服务权限怎么管?怎么设计比较合理?从大层面讲叫服务权限,往小处拆分,分别为三块:用户认证.用户权限.服务校 ...
- AES加密算法详解
AES 是一个对称密码分组算法,分组长度为128bit,密钥长度为128.192 和 256 bit. 整个加密过程如下图所示. 1.密钥生成算法 密钥扩展过程: 1) 将种子密钥按下图所示的格式排 ...
- rest_framework之认证源码剖析
如果我们写API有人能访问,有人不能访问,则需要些认证. 如何知道该用户是否已登入? 如果用户登入成功,则给用户一个随机字符串,去访问另一个页面. 以前写session的时候,都是把session写c ...
- JS 简单工厂模式,工厂模式(二)
一.什么是工厂模式: 工厂模式就是用来创建对象的一种最常用的设计模式,我们不暴露创建对象的具体逻辑,而是将逻辑封装到一个函数中,那么,这个函数 就可以被视为一个工厂.那么,在实际项目中,我们是不是可以 ...
- 判断js中的数据类型的几种方法
判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. $.type()/jquery.type(),接下来主要比较一下这几种方法的异 ...