LeetCode-6.Z 字形变换 - 消费补偿算法
题目
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
解决这题的关键是找到每一行的字符位置规律,根据分析可以知道:
第一行和最后一行的字符位置相差 2*numRows-2
,如下图所示:
而对于其他行来说,字符位置加4会略过当前行的一个字符。如下图所示:
先定义一个money作为这个跨度,即int money = 2*numRows-2
,定义 j 为要访问的s字符串的字符下标。
然后,我打算对当前行做一个"补偿",即让他倒退2个位置。即j = j + money - (2*i - 2)
,这样一来,T的位置就可以在E的基础上算出来(j=1, money=4): 1+4-(2*2-2)=3。
你可以理解为原来我要消费money块钱,现在我补偿回一些钱给你。那么在下次消费时,就要恰好把money消费完。即:money -= money - (2*i - 2)
,即money=4-(2*2-2)=2
,这样就可以访问到O字符了。
这个算法,我称之为消费补偿算法
,还没有看题解,不知道其他大佬的思想是不是类似。下面贴我的代码:
#include <iostream>
#include <string>
using namespace std;
/**
* LeetCode
* 6. Z 字形变换
* https://space.bilibili.com/54183978
*/
class Solution {
public:
string convert(string s, int numRows) {
int size = s.size();
string ans = "";
if(numRows == 1){
return s;
}
for(int i = 1; i <= numRows; i++){
// 加第i行字符
int j = i - 1;
// 每行第一个字符
ans += s[j];
int money = 2*numRows-2;
while(j < size){
if(money == 2*numRows-2 && i!=numRows){
// 消费补偿
j = j + money - (2*i - 2);
if(j >= size){
break;
}
ans += s[j];
money -= money - (2*i - 2);
} else{
// 消费剩余
j = j + money;
if(j >= size){
break;
}
ans += s[j];
money = 0;
}
if(money == 0){
money = 2*numRows-2;
}
}
}
return ans;
}
};
int main(){
Solution solution;
cout << solution.convert("LEETCODEISHIRING", 3);
}
下面是代码评测结果:
- 解决VMware 7在Windows 7上无法上网的问题
- Windows Server 2008群集仲裁机制
- [C#2] 5-迭代器
- 服务器未能识别 HTTP 标头 SOAPAction 的值
- 实用代码-C#获取本机网络适配器信息及MAC地址
- WordPress 自定义 login (登录页面)CSS 样式
- [C#1] 12-特性
- HTTP Basic Authentication for RESTFul Service
- [C#2] 4-可空类型、静态类
- jquery 操作css 尺寸
- Windows 7上IIS出现http 500错误
- [C#2] 2-匿名方法
- jquery 操作css 选择器
- 主页后台源码及释义
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一看就懂的Tensorflow实战(GAN)
- 一看就懂的Tensorflow实战(DCGAN)
- VBA解压缩ZIP文件08——解压-没有压缩
- 一文教你搞懂C语言的Q格式
- 基础算法之排序算法
- C++核心准则E4,5:设计并构建不变量
- Selenium实际应用注入并执行Javascript语句
- 什么是Python的 “内存管理机制”
- 2020年手工webpack构建react项目,完美支持ssr,包括css和图片资源
- php中赋值、浅拷贝与深拷贝
- 2020最新:100道有答案的前端面试题(下)
- UI自动化测试之ddt实战
- KVM 之网络配置
- Mysql操作
- CentOS7+nginx+uwsgi+Django部署之路