首先记住这句话,笔试都遇到好几次了:
从数据结构角度看,栈也是线性表!
目录
Leetcode150.逆波兰表达式求值
LeetCode1021.删除最外层的括号
LeetCode921.使括号有效的最少添加
LeetCode1047.删除字符串中的所有相邻重复项
LeetCode面试题03.04.化栈为队
LeetCode682.棒球比赛
LeetCode496.下一个更大的元素I
Leetcode150.逆波兰表达式求值
————————————————
最经典的一道栈的题目,想当年为了弄懂这题可是花了不少劲,现在看来实属easy!
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for(int i=0;i<tokens.size();i++){
if(tokens[i]=="+"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(a+b);
}else if(tokens[i]=="-"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(b-a);
}else if(tokens[i]=="*"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(a*b);
}else if(tokens[i]=="/"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(b/a);
}else{
st.push(stoi(tokens[i]));
}
}
return st.top();
}
};
————————————————
LeetCode1021.
—
class Solution {
public:
string removeOuterParentheses(string S) {
string res = "";
stack<char> mystack;
for (int i = 0; i < S.size(); i++) {
if (S[i] == ')')
mystack.pop();
if (!mystack.empty())
res+=S[i];
if (S[i] == '(')
mystack.push('(');
}
return res;
}
————————————————
LeetCode921.使括号有效的最少添加
这题是上面那题的姊妹版,同样用栈stack解决,但是注意先判断栈是否为空!
class Solution {
public:
int minAddToMakeValid(string S) {
stack<char> s;
for(int i=0;i<S.size();i++){
if(S[i]=='('||s.empty())//先判断栈是否为空
s.push(S[i]);
else if(S[i]==')'&&s.top()=='(')
s.pop();
else
s.push(S[i]);
}
return s.size();
}
};
————————————————
LeetCode1047.删除字符串中的所有相邻重复项
想一下没有再比这个更明显的栈结构模拟的了……
进阶一点的逆波兰算法:栈解逆波兰算法
class Solution {
public:
string removeDuplicates(string S) {
stack<char> s;
s.push(-1);//开头放进一个不可能的元素放置后面地址错误
for(int i=0;i<S.size();i++){
if(S[i]!=s.top())
s.push(S[i]);
else
s.pop();
}
string ss;
int size = s.size();
for(int i=0;i<size-1;i++){
ss.push_back(s.top());
s.pop();
}
reverse(ss.begin(),ss.end());//结果需要反转
return ss;
}
LeetCode面试题03.04.化栈为队
用两个栈来模拟队列,是一个十分经典的栈与队列问题!
class MyQueue {
public:
/** Initialize your data structure here. */
stack<int> s1,s2;//s1记录队列的压入顺序,s2作转换使用
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
//因为每次pop或者peek的时候都改变了s1,所以push的时候要将s2中的倒回s1
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
s1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int ans = s2.top();
s2.pop();
return ans;
}
/** Get the front element. */
int peek() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
return s2.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return s1.empty()&&s2.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();
LeetCode682.棒球比赛
典型的栈,会逆波兰算法,这个很快就会有思路
class Solution {
public:
int calPoints(vector<string>& ops) {
stack<int> s;
for(int i=0;i<ops.size();i++){
if(ops[i]=="+"){
int a = s.top();
s.pop();
int b = s.top();
s.push(a);
s.push(a+b);
}else if(ops[i]=="C"){
s.pop();
}else if(ops[i]=="D"){
int c = s.top();
s.push(2*c);
}else{
//牢记将string转换成int的方法!
s.push(stoi(ops[i]));
}
}
int ans = 0;
while(!s.empty()){
ans+=s.top();
s.pop();
}
return ans;
}
LeetCode496.下一个更大的元素I
感觉不用用栈就可以做啊
官方题解用单调栈+hashmap,有点小题大做了
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> v;
for(int i=0;i<nums1.size();i++){
bool flag = true;
for(int j = 0;j<nums2.size();j++)
if(nums2[j]==nums1[i])
for(int k = j+1;k<nums2.size();k++)
if(nums2[k]>nums1[i]){
v.push_back(nums2[k]);
flag = false;
break;
}
if(flag)
v.push_back(-1);
}
return v;
}
};
————————————————
维护一个单调递减的栈。
Leetcode 42:接雨水(超详细的解法!!!)
function countSubArray(nums) {
let ans = 0;
let pre = 0;
for (_ in nums) {
pre += 1;
ans += pre;
}
return ans;
}
复制代码
Leetcode 496:下一个更大元素 I(超详细的解法!!!)
function countSubArray(nums) {
let ans = 0;
let pre = 0;
for (_ in nums) {
pre += 1;
ans += pre;
}
return ans;
}
复制代码
Leetcode 503:下一个更大元素 II(超详细的解法!!!)
function countSubArray(nums) {
let ans = 0;
let pre = 0;
for (_ in nums) {
pre += 1;
ans += pre;
}
return ans;
}
复制代码
Leetcode 739:每日温度(超详细的解法!!!)
function countSubArray(nums) {
let ans = 0;
let pre = 0;
for (_ in nums) {
pre += 1;
ans += pre;
}
return ans;
}
复制代码
function countSubArray(nums) {
let ans = 0;
let pre = 0;
for (_ in nums) {
pre += 1;
ans += pre;
}
return ans;
}
复制代码
function countSubArray(nums) {
let ans = 0;
let pre = 0;
for (_ in nums) {
pre += 1;
ans += pre;
}
return ans;
}
复制代码
「224. 基本计算器」、
class Solution {
public int trap(int[] height) {
if(height==null||height.length==0){
return 0;
}
int result=0;
Deque<Integer> stack=new LinkedList<Integer>();
for(int i=0;i<height.length;i++){
int curHeight=height[i];
if(stack.isEmpty()){
stack.push(i);
}else{
while(!stack.isEmpty()&&curHeight>height[stack.peek()]){
//当出现升高的柱子之后,低位柱子最右边的索引
int rightIndex=stack.pop();
if(stack.isEmpty()){
break;
}
//最右边柱子的左边柱子可能之前已经被计算掉了一些,需要用左边未计算的第一个柱子计算
//例如[4,2,0,3,2,5] 3时已经把之前2 0 就算,5时先把2计算,之后应该从4开始计算高度3的量
int leftIndex=stack.peek();
result+=(Math.min(curHeight,height[leftIndex])-height[rightIndex])*(i-leftIndex-1);
}
stack.push(i);
}
}
return result;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
// public ListNode removeNthFromEnd(ListNode head, int n) {
// Deque<ListNode> stack=new LinkedList<ListNode>();
// ListNode tempNode=new ListNode(0,head);
// ListNode curNode=tempNode;
// while(curNode!=null){
// stack.push(curNode);
// curNode=curNode.next;
// }
// while(n>0){
// stack.pop();
// n--;
// }
// if(stack.isEmpty()){
// return null;
// }else{
// stack.peek().next=stack.peek().next.next;
// }
// return tempNode.next;
// }
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head==null||head.next==null){
return null;
}
ListNode fast=head,slow=head;
while(n>0&&fast!=null){
fast=fast.next;
n--;
}
if(fast==null&&n==0){
return head.next;
}
if(fast==null&&n>0){
return null;
}
while(fast!=null&&fast.next!=null){
fast=fast.next;
slow=slow.next;
}
if(slow.next!=null){
slow.next=slow.next.next;
}
return head;
}
}