字符串/双指针/站与队列(高度重复)
一个菜鸡的力扣刷题记录02
字符串
反转字符出
344.反转字符串
2023/8/23
很简单
class Solution{
public:
void reverseString(vector<char>& s){
int len = s.size();
for(auto i = 0; i < len / 2; i++)
{
auto j = len - 1 - i;
auto tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
};
反转字符串Ⅱ
541.反转字符串Ⅱ
2023/8/23
不难
class Solution{
public:
string re(string s, int bg, int ed)
{
while(bg < ed)
{
auto tmp = s[bg];
s[bg] = s[ed];
s[ed] = tmp;
bg++;
ed--;
}
return s;
}
string reverseStr(string s, int k){
int len = s.length();
int left = 0;
while(left < len)
{
int right = left + k - 1;
if(right >= len)
return re(s, left, len - 1);
s = re(s, left, right);
left = right + k + 1;
}
return s;
}
};
替换空格
05.替换空格
2023/8/24
很简单
class Solution {
public:
string replaceSpace(string s) {
string res;
char a = ' ';
for(auto i = 0; i < s.length(); i++)
{
if(s[i] == a)
res += "%20";
else
res += s[i];
}
return res;
}
};
翻转字符串里的单词
151.翻转字符串里的单词
2023/8/29
这几天没怎么刷题,这道题难度还行,有点绕,做出来了,但是代码不是很简洁,看了一些题解,cpp都不是很简洁。
class Solution {
public:
string reverseWords(string s) {
string a = "";
string b = "";
for(auto i = 0; i < s.length(); i++)
{
if(b == " ")
b.pop_back();
if(s[i] == ' ' && b != "")
{
b = b + ' ' + a;
a = b;
b = "";
}
else
b += s[i];
}
if(b != " ")
{
b = b + ' ' + a;
a = b;
}
a.pop_back();
return a;
}
};
左旋转字符串
58.左旋转字符串
2023/8/29
跟简单
class Solution{
public:
string reverseLeftWords(string s, int n) {
string res = "";
string tmp = "";
for(int i = 0; i < s.length(); i++)
{
if(i < n)
tmp += s[i];
else
res += s[i];
}
return res + tmp;
}
};
实现strStr()
28.找出字符串中第一个匹配项的下标
2023/8/30
可以考虑使用kmp算法
class Solution{
public:
int strStr(string haystack, string needle) {
for(int i = 0; i < haystack.length(); i++)
{
int k = i;
int j = 0;
while(haystack[k] == needle[j])
{
if(j == needle.length() - 1)
return i;
k++,j++;
}
}
return -1;
}
};
重复的子字符串
459.重复的子字符串
2023/9/6
有三种求法:
1、遍历
2、kmp
3、构造双倍字符串
#include<iostream>
#include<string>
using namespace std;
class Solution{
public:
bool repeatedSubstringPattern(string s) {
int len = s.length();
if(len == 0 && len == 1) return false;
int num = 1;
for(; num <= len / 2; num++)
{
if(len % num == 0)
{
int start = num;
string t = s.substr(0,num);
while(true)
{
if(t != s.substr(start, num))
break;
start += num;
if(start >= len)
return true;
}
}
}
return false;
}
};
双指针
移除元素
反转字符出
替换空格
翻转字符串里的单词
翻转链表
删除链表的倒数第N个节点
链表相交
环形链表Ⅱ
三数之和
四数之和
栈与队列
用栈实现队列
我心中有愧啊,又好久没有更新了,又好久没有刷算法了。
232.用栈实现队列
2023/10/17
这是耻辱的,又一个多月没有刷算法了,我要把之前的进度补上。
class MyQueue {
public:
stack<int> stIn;
stack<int> stOut;
MyQueue() {
}
void push(int x) {
stIn.push(x);
}
int pop() {
if(stOut.empty())
{
while(!stIn.empty())
{
stOut.push(stIn.top());
stIn.pop();
}
}
int x = stOut.top();
stOut.pop();
return x;
}
int peek() {
if(stOut.empty())
{
while(!stIn.empty())
{
stOut.push(stIn.top());
stIn.pop();
}
}
int x = stOut.top();
return x;
}
bool empty() {
if(stOut.empty() && stIn.empty())
return true;
return false;
}
};
用队列实现栈
####225.用队列实现栈
基础
class MyStack {
public:
queue<int> q;
MyStack() {
}
void push(int x) {
q.push(x);
for(int i = 0; i < q.size() - 1; i++)
{
int tmp = q.front();
q.pop();
q.push(tmp);
}
}
int pop() {
int res = q.front();
q.pop();
return res;
}
int top() {
return q.front();
}
bool empty() {
return q.empty();
}
};
有效的括号
20.有效的括号
还行 不是很难
class Solution {
public:
bool isValid(string s) {
stack<char> kh;
for(auto c: s)
{
if(c == '(' || c == '[' || c == '{')
kh.push(c);
else
{
if(kh.empty())
return false;
char res = kh.top();
kh.pop();
if(c == ')' && res == '(') continue;
else if(c == ']' && res == '[') continue;
else if(c == '}' && res == '{') continue;
return false;
}
}
return kh.empty();
}
};
删除字符串中的所有相邻重复项
1047.删除字符串中的所有相邻重复项
不难,但是一开始用的stack,没想到string可以直接用。
class Solution {
public:
string removeDuplicates(string s) {
string stk;
for(auto c: s)
{
if(!stk.empty() && stk.back() == c)
stk.pop_back();
else
stk.push_back(c);
}
return stk;
}
};
逆波兰表达式求值
150.逆波兰表达式求值
还行,简单级别吧
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for(auto s: tokens)
{
if(s == "+" || s == "-" || s == "*" || s == "/")
{
int a, b, c;
b = st.top();
st.pop();
a = st.top();
st.pop();
if(s == "+")
c = a + b;
else if(s == "-")
c = a - b;
else if(s == "*")
c = a * b;
else if(s == "/")
c = a / b;
st.push(c);
}
else
st.push(stoi(s));
}
return st.top();
}
};
滑动窗口最大值
239.滑动窗口最大值
2023/10/23
周末没更新
用优先队列实现大根堆,好理解代码行数少
用单调队列做,速度快。
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
int n = nums.size();
priority_queue<pair<int, int>> q;
for (int i = 0; i < k; ++i) {
q.emplace(nums[i], i);
}
vector<int> ans = {q.top().first};
for (int i = k; i < n; ++i) {
q.emplace(nums[i], i);
while (q.top().second <= i - k) {
q.pop();
}
ans.push_back(q.top().first);
}
return ans;
}
};
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
int n = nums.size();
deque<int> q;
for (int i = 0; i < k; ++i) {
while (!q.empty() && nums[i] >= nums[q.back()]) {
q.pop_back();
}
q.push_back(i);
}
vector<int> ans = {nums[q.front()]};
for (int i = k; i < n; ++i) {
while (!q.empty() && nums[i] >= nums[q.back()]) {
q.pop_back();
}
q.push_back(i);
while (q.front() <= i - k) {
q.pop_front();
}
ans.push_back(nums[q.front()]);
}
return ans;
}
};