1. 程式人生 > 實用技巧 >Leetcode(easy stack)

Leetcode(easy stack)

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;
    }
}