Leetcode(easy stack)

本文详细介绍了LeetCode中涉及栈的简单题目,包括有效括号、最小栈、用队列实现栈、下一个更大元素、棒球比赛、比较含退格的字符串、删除最外面的括号、删除字符串中所有相邻重复项、用栈操作构建数组以及整理字符串等。通过这些题目,深入理解栈的数据结构及其在解决实际问题中的应用。
摘要由CSDN通过智能技术生成

Leetcode easy stack

leetcode简单题目中的栈的全部题目

20 有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 注意空字符串可被认为是有效字符串。

解题思路:按序读取字符串中的每一位,当读取到 ( , { , [ 三种左边的符号时,向栈中添加一个对应的右结束括号,当读取到 ) , } , ] 的时候,判断栈顶的元素是否与其相对应,如果相对应,弹出栈顶元素,继续读取字符串中的字符,直到结束,若在读取判断的过程中出现了不相等,则直接返回false;

public boolean isVaild(String s){
  if (s.isEmpty()){
    return true;
  }
  Stack<Character> stack = new Stack<Character>();
  for(char c:s.toCharArray()){
    if(c=='(') stack.push(')');
    else if (c=='{') stack.push('}');
    else if (c=='[') stack.push(']');
    else if(stack.empty()||c!=stack.pop()) return false
  }
  if(stack.empty()) return true;
  return false;
}

155 最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) —— 将元素 x 推入栈中。
  • pop() —— 删除栈顶的元素。
  • top() —— 获取栈顶元素。
  • getMin() —— 检索栈中的最小元素。

解题思路:设计两个栈,其中一个栈负责添加元素,另外一个栈的栈顶存放当前最小的元素即可。

class MinStack{
  private Stack<Integer> stack;
  private Stack<Integer> minStack;
  public MinStack(){
    stack = new Stack<>();
    minStack = new Stack<>();
  }
  public void push(int x){
    stack.push(x);
    if(minStack.isEmpty()||x<=minStack.peek()) minStack.push(x);
  }
  public void pop(){
    if(stack.pop().equals(minStack.peek())) minStack.pop();
  }
  public int top(){
    return stack.peek();
  }
  public int getMin(){
    return minStack.peek();
  }
}

225 用队列实现栈

使用队列实现栈的下列操作:

  • push(x) – 元素 x 入栈
  • pop() – 移除栈顶元素
  • top() – 获取栈顶元素
  • empty() – 返回栈是否为空

解题思路:采用两个队列即可

class MyStack{
  private Queue<Integer> queue1;
  private Queue<Integer> queue2;
  public MyStack(){
    queue1 = new LinkedList<>();
    queue2 = new LinkedList<>();
  }
  public void push(int x){
    queue1.add(x);
  }
  public int pop(){
    while(queue1.size()>1) queue2.add(queue1.poll());
    int ans = queue1.poll();
    while(queue2.size()>0) queue1.add(queue2.poll());
    return ans;
  }
  public int top(){
    while(queue1.size()>1) queue2.add(queue1.poll());
    int ans = queue1.peek();
    queue2.add(queue1.poll());
    while(queue2.size()>0) queue1.add(queue2.poll());
    return ans;
  }
  public boolean empty(){
    return queue1.isEmpty();
  }
}

496 下一个更大的元素

给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。

nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。
输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]

解题思路:

class Solution{
  	public int[] nextGreaterElement(int[] nums1,int[] nums2){
      	Stack<Integer> stack = new Stack<>();
      	HashMap<Integer,Integer>map = new HashMap<>();
      	int[] res = new int[nums1.length];
      	for (int i=0;i<nums2.length;i++){
          	while(!stack.empty() && nums2[i]>stack.peek())
              	map.put(stack.pop(),nums2[i])
             stack.push(nums[i]);
        }
      while(!stack.empty){
          map.put(stack.pop(),-1);
      }
      for (int i =0;i<nums1.length;i++)
        	res[i] = map.get(nums1[i])
       return res
    }
}

682 棒球比赛

你现在是棒球比赛记录员。
给定一个字符串列表,每个字符串可以是以下四种类型之一:

  • 1.整数(一轮的得分):直接表示您在本轮中获得的积分数。
    1. “+”(一轮的得分):表示本轮获得的得分是前两轮有效 回合得分的总和。
    1. “D”(一轮的得分):表示本轮获得的得分是前一轮有效 回合得分的两倍。
    1. “C”(一个操作,这不是一个回合的分数):表示您获得的最后一个有效 回合的分数是无效的,应该被移除。

每一轮的操作都是永久性的,可能会对前一轮和后一轮产生影响。
你需要返回你在所有回合中得分的总和。

class Soultion{
  public int calPoints(String[] ops){
    int res = 0;
    Stack<Integer> stack = new Stack<>();
    for(String str:ops){
      switch (str){
        case "C":
          stack.pop();
          break;
        case "D":
          stack.push(stack.peek()*2);
          break;
        case "+":
          Integer tmpPeek = stack.pop();
          Integer tmp = stack.peek()+tmpPeek;
          stcak.push(tmpPeek);
          stack.push(tmp);
        default:
          stack.push(Integer.valueOf(str));
          break;
      }
    }
    while(!stack.empty) res+=stack.pop();
    return res;
  }
}

844 比较含退格的字符串

给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

class Solution{
  public boolean backsapceCompare(String S,String T){
    return build(S).equals(build(T));
  }
  public String build(String str){
    Stack<Character> stack = new Stack<>();
    for(Char c:str.toCharArray()){
      if(c!='#') stack.push(c);
      else if(!stack.empty()) stack.pop();
      return String.vauleOf(stack);
    }
  }
}

1021 删除最外面的括号


class Solution{
  public String removeOuterParentheses(String S){
    StringBuilder str = new StringBuilder();
    int num = 0;
    int index = 0;
    for(int i=0;i<S.length();i++){
      if(S.charAt(i)=='(') num++;
      if(S.charAt(i)==')') num--;
      if(num==1 && S.charAt(i)=='(') index =i;
      if(num ==0) str.append(S.subString(index+1,i));
    }
    return str.toString();
  }
}
class Solution {
    public String removeOuterParentheses(String S) {
        StringBuilder sb = new StringBuilder();
        int level = 0;
        for (char c : S.toCharArray()) {
            if (c == ')') --level;
            if (level >= 1) sb.append(c);
            if (c == '(') ++level;
        }
        return sb.toString();
    }
}


1047 删除字符串中所有的相邻重复项

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

class Solution {
    public String removeDuplicates(String S) {
        Stack<Character> stack = new Stack<>();
        for(Character c : S.toCharArray()){
            if(stack.isEmpty()) stack.push(c);
            else if(c==stack.peek()) stack.pop();
            else stack.push(c);
        }
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty()) sb.append(stack.pop());
        return sb.reverse().toString();
    }
}

1441 用栈操作构建数组

给你一个目标数组 target 和一个整数 n。每次迭代,需要从 list = {1,2,3…, n} 中依序读取一个数字。

请使用下述操作来构建目标数组 target :

  • Push:从 list 中读取一个新元素, 并将其推入数组中。
  • Pop:删除数组中的最后一个元素。
    如果目标数组构建完成,就停止读取更多元素。
    题目数据保证目标数组严格递增,并且只包含 1 到 n 之间的数字。

请返回构建目标数组所用的操作序列。

题目数据保证答案是唯一的。

class Solution {
    public List<String> buildArray(int[] target, int n) {
        List<String> list = new ArrayList<>();
        int flag = 1;
        for(int num:target){
            if(num==flag) list.add("Push");
            else{
                while(num!=flag){
                    list.add("Push");
                    list.add("Pop");
                    flag++;
                }
                list.add("Push");
            }
            flag++;
        }
        return list;
    }
}

1544 整理字符串

class Solution {
    public String makeGood(String s) {
        Stack<Character> stack = new Stack<>();
        for(Character c:s.toCharArray()){
            if(stack.isEmpty()) stack.push(c);
            else{
                if(stack.peek()+32==c || stack.peek()-32 ==c) stack.pop();
                else stack.push(c);
            }
        }
        StringBuilder sb = new StringBuilder();
        for(Character c:stack) sb.append(c);
        return sb.toString();
    }
}

5523 文件夹操作日志收集器

class Solution {
    public int minOperations(String[] logs) {
        int step = 0;
        for(String str:logs){
            if(str.equals("../")){
                if(step!=0){
                    step--;
                }
            }
            else if(str.equals("./")) continue;
            else{
                step++;
            }
        }
        return step;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值