LeetCode——数据结构训练(栈、队列、哈希和字符串)
题号目录网址 (只做了部分题)
对应题号到LeetCode搜索
主要是在算法里面的应用
232. 用栈实现队列(简单题)
就移除队列那边注意下就好了
class MyQueue {
private:
stack<int> inStack, outStack;
void inOut(){
while(!inStack.empty()){
outStack.push(inStack.top());
inStack.pop();
}
}
public:
/** Initialize your data structure here. */
MyQueue() {}
/** Push element x to the back of queue. */
void push(int x) {
inStack.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
if(outStack.empty()){
inOut();
}
int x = outStack.top();
outStack.pop();
return x;
}
/** Get the front element. */
int peek() {
if(outStack.empty()){
inOut();
}
return outStack.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return inStack.empty()&&outStack.empty();
}
};
225. 用队列实现栈(简单题)
class MyStack {
private:
queue<int> q;
public:
/** Initialize your data structure here. */
MyStack() {}
/** Push element x onto stack. */
void push(int x) {
q.push(x);
int sz = q.size();
while(sz-->1){
q.push(q.front());
q.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int r = q.front();
q.pop();
return r;
}
/** Get the top element. */
int top() {
return q.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return q.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();
*/
155. 最小栈(简单题)
记得设置初始最大值
// 记得设置初始最大值
class MinStack {
private:
stack<int> currStack, minStack;
public:
/** initialize your data structure here. */
MinStack() {
//很重要
minStack.push(INT_MAX);
}
void push(int val) {
currStack.push(val);
minStack.push(min(minStack.top(),val));
}
void pop() {
currStack.pop();
minStack.pop();
}
int top() {
return currStack.top();
}
int getMin() {
return minStack.top();
}
};
20. 有效的括号(简单题)
class Solution {
public:
bool isValid(string s) {
stack<char> str;
for(char c:s){
// 也可以用这个map来存储这些
if(c=='{'||c=='['||c=='('){
str.push(c);
}
else{
if(str.empty()){
return false;
}
if(c=='}'&&str.top()=='{'||c==']'&&str.top()=='['||c==')'&&str.top()=='('){
str.pop();
}else{
return false;
}
}
}
if(!str.empty()) return false;
return true;
}
};
定义map存储符号
class Solution {
public:
bool isValid(string s) {
//定义哈希,便于对输入还是输出做判断
unordered_map<char,int> m{{'(',1},{'[',2},{'{',3},
{')',4},{']',5},{'}',6}};
stack<char> str;
bool res = true;
for(char c:s){
int flag = m[c];
if(flag<=3)str.push(c);//如果是输入就进栈
else if(!str.empty()&&m[str.top()]==flag-3)str.pop();//输出做比较,相同退栈,否则退出循环
else{
res =false;
break;
}
}
if(!str.empty())res = false;
return res;
}
};
739. 每日温度(中等题)
理解好题目,要的差了几天,就是下标差
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int sz = temperatures.size();
vector<int> res(sz);
stack<int> stk;
for(int i=0;i<sz;i++){
// 这个栈和while是精髓
while(!stk.empty() && temperatures[i]>temperatures[stk.top()]){
int preIndex = stk.top();
res[preIndex] = i-preIndex;
stk.pop();
}
stk.push(i);
}
return res;
}
};
503. 下一个更大元素 II(中等题)
跟上面那题相比,主要是数组是循环的
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n, -1);
stack<int> s;
// 这里直接等于遍历两次,就是将数组扩大了一倍
for(int i=0;i<2*n-1;i++){
while(!s.empty()&&nums[i%n]>nums[s.top()]){
ans[s.top()] = nums[i%n];
s.pop();
}
s.push(i%n);
}
return ans;
}
};
1. 两数之和(简单题)
map来记录已经遍历的数,防止数重复使用。另外就是hash查找更快,可以查找到两数之和
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i=0;i<nums.size();i++)
{
if(m.find(target-nums[i])!=m.end()&&m[target-nums[i]]!=i)
return {m[target-nums[i]],i};
m[nums[i]]=i;
}
return {};
}
};
2. 字符串循环移位(编程之美 2.17)
s = "abcd123" k = 3
Return "123abcd"
将字符串向右循环移动 k 位。将 abcd123 中的 abcd 和 123 单独翻转,得到 dcba321,然后对整个字符串进行翻转,得到 123abcd。
3. 字符串中单词的翻转(程序员代码面试指南)
s = "I am a student"
Return "student a am I"
// 将每个单词翻转,然后将整个字符串翻转。
LeetCode上面还有很多字符串的,不写啦,基本都在前面几题,什么回文字符串啥的。
总结
栈和队列主要是先进后出和先进先出,然后就是各自的一些应用,树和图还有很多地方。哈希的话理解下,字符串基本都是一些基础算法题,可以自己看看。