[LeetCode]String主题系列{第5,6题}
时间:2022-05-06
本文章向大家介绍[LeetCode]String主题系列{第5,6题},主要内容包括1.内容介绍、2.题目和解题过程、2.2 ZigZag Conversion、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
1.内容介绍
本篇文章记录在leetcode中String主题下面的题目和自己的思考以及优化过程,具体内容层次按照{题目,分析,初解,初解结果,优化解,优化解结果,反思}的格式来记录,供日后复习和反思[注:有些题目的解法比较单一,就没有优化过程]。题目的顺序按照leetcode给出的题目顺序,有些题目在并不是按照题目本身序号顺序排列的,也不是严格按照难易程度来排列的。
因此,这篇文章并不具有很强的归类总结性,归类总结性知识将会在其他文章记录,本篇重点在记录解题过程中的思路,希望能对自己有所启发。
2.题目和解题过程
2.1 Longest Palindrome String
- 题目:Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.Example: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example: Input: "cbbd" Output: "bb"
- 分析:咋一看题,有点蒙,题目要求:回文字符串,最长的。假设在1000个字符长度的字符串中搜索回文串,该怎么搜索呢?直接从头开始搜索?判断回文串的核心是确定首尾位置,然后向中间移动并对比首尾位置的字符是否相同,而现在并不知道哪些连续的子串是回文串,也就不知道回文串确切的长度,要知道,搜索一定是按照某种模式(逻辑)来进行的,所以不管效率高低,首先得确定有哪些可以用的搜索模式。最简单的就是按照从首字符开始枚举回文串长度在[1, length]范围进行逐个长度进行判断,然后再逐字符向后迭代重复枚举检查。显然,复杂度太高,但是搜索模式似乎不太可能改,因此优化的方向大概是根据回文串的特点结合当前搜索结果进行快速过滤不可能出现在回文串中的字符。
- 初解:对于字符串中每个字符,假设它为回文串的首位置,然后取字符串最后一个字符为回文串尾位置,判断是否是回文串,若是则记录,否则将尾部向前移动一个位置,重复判断直到首尾相遇,然后将首位置向后移动一个位置,直到字符串结束。从长向短搜索的一个好处是如果已经搜索到一个较长的回文串,那么就不必再继续在原位置向后搜索。
class Solution {
public:
string longestPalindrome(string s) {
if(s.size() <= 1)
return s;
string res ="";
int length = 0;
for(int i = 0; i < s.size(); ++i)
{
if((s.size() - i) < length)
break;
for(int j = s.size() - 1; j > i; --j)
{
int tmp_length = j - i + 1;
if(tmp_length < length)
break;
if(s[i] == s[j])
{
int start = i, end = j;
while(start < end)
{
if(s[++start]!=s[--end])
break;
}
if(start >= end)
{
res = s.substr(i,tmp_length);
length = tmp_length;
break;
}
}
}
}
if(res == "")
res = s[0];
return res;
}
};
- 初解结果:
- 优化解法:
- 优化结果:
- 反思:
2.2 ZigZag Conversion
- 题目:
- 分析:这道题属于花式打印的题目类型,所以只要找到打印的规律就能求解。
- 初解:最简单的解法,直接从每一行每一列观察打印的规律,发现收尾两行的字符数量相等,而中间的行多出了一些字符,如果将这些多出来的字符P,S,I分别看做与左边相邻的3个字符是一个group的话,就可以按照组的长度将字符分组,并将同一个组内的字符根据位置分配到相应的行上,最终再将各行相加即可。
class Solution {
public:
string convert(string s, int numRows) {
if(numRows <= 1)
return s;
vector<string> res(numRows,"");
int group_length = numRows + numRows - 2;
for(int rows = 0; rows < numRows; ++rows)
{
int revise = 0;
if(rows > 0 || rows < numRows-1)
revise = rows;
for(int i = 0; i < s.size(); ++i)
{
if(((i+revise)%group_length)==0 || ((i-revise)%group_length)==0)
res[rows]+=s[i];
}
}
string total = "";
for(auto iter:res)
total+=iter;
return total;
}
};
- 初解结果:
- 优化解法:初解中在求解每一行的字符时都需要遍历整个字符串,因此效率低,如果仅仅遍历一次字符串就能将各个字符分配到对应的行上,这就能节省很多时间。这代表处理每一个字符时就能计算出该字符属于哪一行中的,也就是说找到行变化的规律就能在O(n)的时间复杂度下解决问题,在这个思路下按照原来的字符串顺序观察出现在每行上的顺序,可以看到行的编号是在[0, numRows]之间来回震荡的,结果不言而喻。
class Solution {
public:
string convert(string s, int numRows) {
if(numRows <= 1 || s.size()<=1)
return s;
vector<string> res(numRows,"");
int row=0, step=1;
for(int i=0; i < s.size(); ++i)
{
res[row]+=s[i];
if (row == 0)
step = 1;
else if (row == numRows - 1)
step = -1;
row += step;
}
string total = "";
for(auto iter:res)
total+=iter;
return total;
}
};
- 优化结果:
- 反思:花式打印要观察行或者列的变化规律来解决问题。
- Docker容器学习梳理--容器登陆方法梳理(attach、exec、nsenter)
- java学习:调用 java web service
- java学习:数据增删改查、存储过程调用及事务处理
- 极客手工:自制51四驱无线遥控小车
- flash:二次贝塞尔曲线应用-生成飞机路径示意图
- 微信小程序重磅功能上线!一键连Wi-Fi/手机变门禁卡
- MySQL下载安装、基本配置、问题处理
- windows下命令行模式中cd命令无效的原因
- 分布式和集群区别?什么是云计算平台?分布式的应用场景?
- 中国移动也要搞自动驾驶,没了SIM卡怎么耍花样?
- python并发编程之多进程理论部分
- 使用concurrent.futures模块并发,实现进程池、线程池
- 人工智能与医疗
- 每周论文清单:知识图谱,文本匹配,图像翻译,视频对象分割
- 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 数组属性和方法