问题:

6. Z字形变换

链接:https://leetcode-cn.com/problems/zigzag-conversion/description/

分析:

A 仿真方法

直接模拟整个过程,首先根据字符串大小和行数确定整体所在的行和列,初始化为某一个用不到的字符,比如#,然后按照给定的规则,即Z字型填充,填充完成后每行的结果剔除掉占位符#,重组为最终结果即可。

其中:

1.行数numRows,则2*numRows-1为一个周期,行号上先向下递增,到numRows后向上递减,列号上前面numRows个相同,后面递增

2.每个周期为一组,则groupsize=2*numRows-1,groupwidth=1 + numRows - 2

B 数学方法

按照数字写下了后可以发下如下规律:

0       8       16       24    
1     7 9     15 17     23 26    
2   6   10   14   18   22   27   31
3 5     11 13     19 21     28 30  
4       12       20       29    

1.行与行之间没有影响关系,比如上表中,5在4的右上方和正上方没有区别

2.对于行数numRows,第一行都是坐标为2*(numRows-1)的整数倍,即假设用vector<string> tmp 存储临时的每一行数据,则对于所有的j%(2*numRows-1)==0,s[j]在tmp[0]中

3.类似的,如果余数±m,则在tmp[m]中,比如对于7和9,对8求模可以视为±1,都在tmp[1]中。

4.简化一下,numRows行,对于str中的第i个元素,则满足:

如果mod1=i%(2*numRows-2)<=numrows-1,则在tmp[mod1]行

否则在tmp[2*numRows-2-mod1]行

AC Code:

class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1)
{
return s;
}
string ret = "";
int length = s.size();
int col = GetColumn(length,numRows);
//char chars[][] = new char[numRows][col]; string initstr = "";
for (int i = 0; i < col; i++)
{
initstr += "#";
}
vector<string> tmp(numRows,initstr);
int groupsize = 2 * numRows - 2; //一组的个数,一整列整列减去2
int groupwidth = 1 + numRows - 2; //本身一列,去掉头尾各占一列
if (s.size() <= groupsize)
{
FileGroup(tmp, s, 0);
}
else
{
string tmpstr = "";
int index = 0;
int rolnum = 0;
while (true) //每次取一组处理
{
if (index+ groupsize >= s.size())
{
tmpstr = s.substr(index, s.size() - index);
FileGroup(tmp, tmpstr, rolnum);
break;
}
tmpstr = s.substr(index, groupsize);
FileGroup(tmp, tmpstr, rolnum);
index += groupsize;
rolnum += groupwidth;
}
}
for (int i = 0; i < tmp.size(); i++)
{
ret += GenerateStrs(tmp[i]);
}
return ret;
}
string GenerateStrs(string str)
{
string ret = "";
for (int i = 0; i < str.size(); i++)
{
if (str[i] != '#')
{
ret += str[i];
}
}
return ret;
}
void FileGroup(vector<string>& data, string str, int begin)
{
int linenum = 0;
int rowlinumber = begin;
int direction = 1;
for (int i = 0; i < str.size(); i++)
{
if (direction == 1)
{
data[linenum][rowlinumber] = str[i];
linenum += direction;
}
else
{
data[linenum][rowlinumber] = str[i];
linenum += direction;
rowlinumber++;
} if (linenum == data.size() - 1)
{
direction = -1;
}
}
}
int GetColumn(int size, int rows)
{
int ret = 1;
if (size <= rows)
{
ret = 1;
return ret;
}
int groupsize = 2 * rows - 2; //一组的个数,一整列整列减去2
int groupwidth = 1 + rows - 2; //本身一列,去掉头尾各占一列
if (size <= groupsize)
{
ret = groupwidth - (groupsize - size);
return ret;
}
ret = size / groupsize * groupwidth + GetColumn(size%groupsize, rows); return ret;
}
};

  

class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1)
{
return s;
}
string ret = "";
vector<string> tmp(numRows);
for (int i = 0; i < s.size(); i++) //以2*(numRows-1)+1为周期
{
if (i % (2*numRows-2 )<=(numRows-1) ) //向下
{
tmp[i % (2 * numRows -2)] +=s[i];
}
else //向上
{
tmp[2*numRows-2- i % (2 * numRows -2)] += s[i];
} }
for (int i = 0; i < numRows; i++)
{
ret += tmp[i];
}
return ret;
}
};

  

其他:

1.难得回来早一点,https://my.youdias.xin/tools/chooser.html 上随机决定做一道LeetCode,就按顺序做了这个,看到题目的第一反应就是模拟过程来处理,写code的过程中感觉到应该是有规律的,完成仿真过程后提交,战胜18.59%,实现数学方法,战胜68.61%,计算机思维是把双刃剑,如果想要提高效率,还是得用脑子。

2.用时最短的code

static const auto io_sync_off = []()
{
// turn off sync
std::ios::sync_with_stdio(false);
// untie in/out streams
std::cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
string convert(string s, int numRows) {
if(numRows == 1) return s;
int size = (numRows<<1) - 2;
char res[s.size()+1];
int index = 0;
for(int i = 0; i < numRows; i++){
for(int j = i; j < s.size(); j += size){
res[index++] = s[j];
int tmp = j + size - (i<<1);
//j是前一个黑色元素在原数组中的下标,i是画成之字形时的行数
if(i > 0 && i < numRows-1 && tmp <s.size()){
res[index++] = s[tmp];
}
}
}
res[s.size()] = '\0';
return res;
}
};

  

LeetCode_6的更多相关文章

  1. Leetcode_6. Zigzag convertion

    6. Zigzag convertion 对输入的字符串做锯齿形变换,并输出新的字符串,所谓zigzag变化如下图所示. 将"ABCDEFGHIJKL"做4行的锯齿变换,新的字符串 ...

随机推荐

  1. 关于java多线程任务执行时共享资源加锁的方式思考

    1.加锁方式: 1-1.使用synchronized关键字进行方法或代码块的加锁方式 1-2.使用ReentrantLock类提供的lock()方法的方式 2.代码实现(传统的银行取款存款问题): 2 ...

  2. [LOJ 2190] 「SHOI2014」信号增幅仪

    [LOJ 2190] 「SHOI2014」信号增幅仪 链接 链接 题解 坐标系直到 \(x\) 轴与椭圆长轴平行 点的坐标变换用旋转公式就可以了 因为是椭圆,所以所有点横坐标除以 \(p\) 然后最小 ...

  3. HDU-2063-过山车(最大匹配)

    链接:https://vjudge.net/problem/HDU-2063 题意: RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且 ...

  4. 51nod1244 莫比乌斯函数之和 杜教筛

    虽然都写了,过也过了,还是觉得杜教筛的复杂度好玄学 设f*g=h,∑f=S, 则∑h=∑f(i)S(n/i下取整) 把i=1时单独拿出来,得到 S(n)=(∑h-∑2->n f(i)S(n/i下 ...

  5. Consul实现服务治理1

    NET Core微服务之基于Consul实现服务治理 https://www.cnblogs.com/edisonchou/p/9148034.html 一.Consul服务注册之配置文件方式 1.1 ...

  6. AtCoder Regular Contest 075 2017年6月4日 C、D、E题解

    http://arc075.contest.atcoder.jp/assignments 昨晚做的atcoder,今天写个简单题解. F题不会做,800point的,就跪了,要等zk大佬来做.zk能做 ...

  7. (转)Linux下select, poll和epoll IO模型的详解

    Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...

  8. 《从0到1学习Flink》—— 如何自定义 Data Source ?

    前言 在 <从0到1学习Flink>-- Data Source 介绍 文章中,我给大家介绍了 Flink Data Source 以及简短的介绍了一下自定义 Data Source,这篇 ...

  9. 09SpringAopAdvice

    Spring原生的经典模式 实现 AOP 通知: 前置通知:在目标方法执行之前执行,不能改变方法的执行流程和结果! 实现 MethodBeforeAdvice接口! 后置通知:在目标方法执行之后执行, ...

  10. 第十六章 提升用户体验 之 设计实现routes

    1. 概述 ASP.NET MVC route 用来把URL映射到方法中的action,是用户和程序之间的桥梁. 本章内容包括:定义route处理URL Pattern.应用route限制.忽略URL ...