344.反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
int i = 0,j = s.size()-1;
while(i < j){
swap(s[i], s[j]);
i++;
j--;
}
return;
}
};
541. 反转字符串II
class Solution {
public:
string reverseStr(string s, int k) {
for(int i = 0; i < s.size(); i += 2 * k){
if(i + k <= s.size() - 1 ) reverse(s.begin()+i, s.begin()+i+k);
if(i + k > s.size() - 1) reverse(s.begin()+i, s.end());
}
return s;
}
};
剑指Offer 05.替换空格
class Solution {
public:
string replaceSpace(string s) {
for(int i =0; i < s.size(); i++){
if(s[i]==' ') {
s.erase(i,1);//删掉空格
s.insert(i,"%20");//插入%20
}
}
return s;
}
};
151.翻转字符串里的单词
class Solution {
public:
// 反转一个单词的函数
void reverse(string& s, int start, int end){
for (int i = start, j = end; i < j; i++, j--) {
swap(s[i], s[j]);
}
}
//去除所有空格并在相邻单词之间添加空格, 快慢指针。
void removeExtraSpaces(string& s) {
int slow = 0;
for (int i = 0; i < s.size(); i++) { //
if (s[i] != ' ') { //遇到非空格就处理,即删除所有空格。
if (slow != 0) s[slow++] = ' ';
//手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。
while (i < s.size() && s[i] != ' ') { //补上该单词,遇到空格说明单词结束。
s[slow++] = s[i++];
}
//i--;
}
}
s.resize(slow); //slow的大小即为去除多余空格后的大小。
}
string reverseWords(string s) {
removeExtraSpaces(s); //去除多余空格
reverse(s, 0, s.size() - 1);
int start = 0; //removeExtraSpaces后保证第一个单词的开始下标一定是0。
for (int i = 0; i <= s.size(); ++i) {
if (i == s.size() || s[i] == ' ') { //到达空格或者串尾,说明一个单词结束。进行翻转。
reverse(s, start, i - 1); //翻转,注意是左闭右闭 []的翻转。
start = i + 1; //更新下一个单词的开始下标start
}
}
return s;
}
};
剑指Offer58-II.左旋转字符串
class Solution {
public:
string reverseLeftWords(string s, int n) {
//n = n % s.size();
string t = s.substr(0, n);//s.substr(begin(), n)这种用法不对
s.erase(0, n);
s += t;
return s;
}
};
232.用栈实现队列
class MyQueue {
public:
stack<int> st1;
stack<int> st2;//辅助
MyQueue() {
}
void push(int x) {
st1.push(x);
}
int pop() {
while(!st1.empty()){
st2.push(st1.top());
st1.pop();
}
int x= st2.top();
st2.pop();
while(!st2.empty()){
st1.push(st2.top());
st2.pop();
}
return x;
}
int peek() {
while(!st1.empty()){
st2.push(st1.top());
st1.pop();
}
int x= st2.top();
//st2.pop();
while(!st2.empty()){
st1.push(st2.top());
st2.pop();
}
return x;
}
bool empty() {
return st1.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
225. 用队列实现栈
class MyStack {
public:
deque<int> que;
MyStack() {
}
void push(int x) {
que.push_back(x);
}
int pop() {
int n = que.size()-1;
while(n--){
que.push_back(que.front());
que.pop_front();
}
int x = que.front();
que.pop_front();
return x;
}
int top() {
int x = pop();
que.push_back(x);//注意这里是push_back不是push_front
return x;
}
bool empty() {
return que.empty();
}
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
20. 有效的括号
class Solution {
public:
bool isValid(string s) {
if(s.size()%2==1) return false;
stack<int> zhan;
for(int i=0;i<s.size();i++){
if(s[i]=='(') zhan.push(')');
else if(s[i]=='[') zhan.push(']');
else if(s[i]=='{') zhan.push('}');
else if(zhan.empty()||s[i]!=zhan.top()){
return false;
}else zhan.pop();//相等的情况
}
return zhan.empty();//注意这里不能直接返回true,因为有这样一种情况"(("不合法
}
};
1047. 删除字符串中的所有相邻重复项
class Solution {
public:
string removeDuplicates(string s) {
if(s.empty()) return s;
stack<char> sta;
sta.push(s[0]);
for(int i=1;i<s.size();i++){
if(!sta.empty()&&sta.top()==s[i]){
//如果我们尝试执行 sta.top() == s[i] 语句,但是栈内没有任何元素,程序就会产生一个运行时错误。解决这个问题最简单的方法是在判断栈是否为空之前,先判断一下栈是否至少拥有第一个字符串元素。
//top前一定要判断非空
sta.pop();
}else sta.push(s[i]);
}
string res="";
while(!sta.empty()){
res+=sta.top();
sta.pop();
}
reverse(res.begin(),res.end());//还要反转一下
return res;
}
};
150. 逆波兰表达式求值
class Solution {
public:
int evalRPN(vector<string>& s) {
//要先判断符号,如果先判断数字,数字里有负数比如-11这样的数字,判断起来比较麻烦
stack <int> stack;
for(int i=0;i<s.size();i++){
if(s[i] =="+"||s[i] =="-"||s[i] =="*"||s[i] =="/"){
int s1=stack.top();
stack.pop();
int s2=stack.top();
stack.pop();
int s3;
if(s[i] =="+") s3=s1+s2;
if(s[i] =="-") s3=s2-s1;
if(s[i] =="*") s3=s1*s2;
if(s[i] =="/") s3=s2/s1;//还有这个顺序也需要注意
stack.push(s3);
}else{
stack.push(stoi(s[i]));//这个函数字符串转整型
}
}
return stack.top();
}
};
239. 滑动窗口最大值
class myQue {
public:
deque<int> myq;
// pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
// push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止
// 保持如上规则,每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。
void push(int x){
while(!myq.empty() && x > myq.back()){
myq.pop_back();
}
myq.push_back(x);
}
void pop(int x){
if(x==myq.front()) myq.pop_front();
}
int front(){
return myq.front();
}
};
class Solution {
public:
//利用单调队列来做,保证队列头到队列尾递减
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
myQue que;
for(int i=0; i < k; i++){
que.push(nums[i]);
}
vector<int> res;
res.push_back(que.front());
for(int i=k; i < nums.size(); i++){
//先push还是先pop,发现都可以过
que.pop(nums[i-k]);
que.push(nums[i]);
res.push_back(que.front());
}
return res;
}
};
347.前 K 个高频元素
class Solution {
public:
//一个思路是,定义一个哈希表遍历一边数组,再将里面的键值对放进一个数组里,再进行排序
vector<int> topKFrequent(vector<int>& nums, int k) {
//vector<pair<int,int>> arr;
vector<int>res ;
unordered_map<int ,int> umap;
for(int i =0; i<nums.size(); i++){
umap[nums[i]]++;
}
vector<pair<int,int>> arr(umap.begin(),umap.end());
sort(arr.begin(), arr.end(), cmp);
for(int i = 0; i < k; i++){
res.push_back(arr[i].first);
}
return res;
}
static bool cmp(pair<int, int> &a, pair<int, int> &b){
return a.second > b.second;
}
};