总结教训:之前刷题太过于随机,今后专项练习;首先为了熟练掌握基本函数,先按照数据结构进行分 类刷题;每一类刷上四五道并对函数进行总结;之后的话在按照算法进行分类刷题。
此次刷题来自剑指offer2的简单中等题。
剑指offer2刷题记录
一、字符串类
1、string函数总结(遇到一个总结一个)
链接: std::basic_string
一定要熟悉这些基本函数的返回值的类型和内容(以下内容有些没有测试)
#include<string> //string 和string.h 是不同的,后者是C语言
//初始化
string s="abc";
//赋值函数
s.assign("word");
int a = s.length(); //不包括 '\0';
//类型转换
atoi(str.c_str());//atoi()用来转换char型到int,c_str()把string 转换成char
stoi(str);//string->int;
stof(str);//string->float;
//切割
string str = s.substr(0,2);//切割字符串 s[0]~s[0+2],第二个参数默认值为字符串结束(size())
//查找
string::size_type pos =find("rl");
//若有返回值为第一次查找到该字符的位置,若没有返回 string的公开静态成员常量npos;
pos =find_first_of("rl");
//find与find_first_of的区别是,find要求查找的字符串完全符合,后者只需要字符串中有个一字符能找到就可以
//rfind是从后往前找,find_last_of亦然。
//插入
s.insert(pos,"666");
#include<string>
#include<iostream>
using namespace std;
template<typename T>
static string strJoin( const string &delim,const T&vec) {
ostringstream s;
for (const auto& i : vec) {
if (&i != &vec[0]) {
s << delim;
}
s << i;
}
return s.str();
}
// vector->string
template<typename T>
static string getVectorString(vector<T>&list) {
return"[" + strJoin(",", list) + "]";
}
2、题目列表
剑指 Offer 05. 替换空格
//偷懒解法,使用了find()和insert()两个函数
class Solution {
public:
string replaceSpace(string s) {
while( s.find(' ') != string::npos){
int a=s.find(' ');
s[a]='%';
s.insert(a+1,"20");
}
return s;
}
};
//手写遍历,另外还有双指针法。简单记一下;
class Solution {
public:
string replaceSpace(string s) {
int count = 0, len = s.size();
// 统计空格数量
for (char c : s) {
if (c == ' ') count++;
}
// 修改 s 长度
s.resize(len + 2 * count);
// 倒序遍历修改
for(int i = len - 1, j = s.size() - 1; i < j; i--, j--) {
if (s[i] != ' ')
s[j] = s[i];
else {
s[j - 2] = '%';
s[j - 1] = '2';
s[j] = '0';
j -= 2;
}
}
return s;
}
};
作者:jyd
链接:https://leetcode.cn/problems/ti-huan-kong-ge-lcof/solution/mian-shi-ti-05-ti-huan-kong-ge-ji-jian-qing-xi-tu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
剑指 Offer 48. 最长不含重复字符的子字符串
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
循环暴力解法:使用了find函数,两层循环。(这应该是双指针吧,外层是左,内层是右)
第一层循环是temp的起始位置,第二层循环就是判断后续每个字符是否存在于temp中,
存在的话就终止该层循环,进行temp和ans的比较,不存在的话就将当前字符插入到temp末尾。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
string ans;
string temp;
if(s.size()==0) return 0;
for(int i=0;i<s.size();i++){
for(int j=i;j<s.size();j++){
if(temp.size()!=0 && temp.find(s[j])!=string::npos) break;
else temp.push_back(s[j]);
}
if(temp.size()>ans.size()) ans=temp;
temp.clear();
}
return ans.size();
}
};
上述解法时间复杂度高,还有双指针/动态规划+哈希表的方法,这里给出双指针+哈希表;
时间复杂度降低,空间复杂度更高,
与上个解法不同的是,这里只需要清除重复项set.erase(s[i]); 不用clear()完了重新插入。
关于set、map等哈希表内容以后再详细了解。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char>set;
int j = 0;
int res = 0;
//外层循环是左指针,内层循环是右指针。
for (int i = 0; i < s.size(); i++){
while(j < s.size() && set.find(s[j]) == set.end()){
set.insert(s[j]);//没有找到就插入
res = max(res, j - i + 1);
j++;
}
set.erase(s[i]);
}
return res;
}
};
1047. 删除字符串中的所有相邻重复项
之前做过的题(简单)
简单一个栈就可以解决。
例子:
输入"abbbccdddca" 输出 aa; 连续三个及以上的字符消除,不断循环,直至没有连续三个以上。
//好好学习下!!! 竟然如此简单,自己想了半天还是只能解决一部分问题。
void del(string& s){
int i = 0, j = 0;
while (i < s.size()) {
j = i;//j为数组坐标 j到i的距离就是重复的个数
while (j < s.size() && s[j] == s[i]){
j++;
}
if (j - i >= 3){
s.erase(i, j - i);//消除重复的
i = i - 2;//回退2个,如1122221,1222211//最多回退两个就可以,因为三个就会消除
if (i < 0)
i = 0;
}
else
i++;
}
}
93.复原IP地址
之前做过的题(较难)
会用到 DFS/递归 ,