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.整數(一輪的得分):直接表示您在本輪中獲得的積分數。
-
- "+"(一輪的得分):表示本輪獲得的得分是前兩輪有效 回合得分的總和。
-
- "D"(一輪的得分):表示本輪獲得的得分是前一輪有效 回合得分的兩倍。
-
- "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;
}
}