棧相關演算法
阿新 • • 發佈:2018-11-21
給定一個只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字串,判斷字串是否有效。
有效字串需滿足:
- 左括號必須用相同型別的右括號閉合。
- 左括號必須以正確的順序閉合。
注意空字串可被認為是有效字串。
class Solution { public boolean isValid(String s) { if (s == null || s.length() == 0) { return true; } final char[] charArray = s.toCharArray(); final Stack<Character> stack = new Stack<Character>(); for (char c : charArray) { if (c == '(' || c == '{' || c == '[') { stack.add(c); } else if (c == ')' || c == '}' || c == ']') { if (stack.isEmpty()) { return false; } if (c == ')' && stack.peek() == '(') { stack.pop(); } else if (c == '}' && stack.peek() == '{') { stack.pop(); } else if (c == ']' && stack.peek() == '[') { stack.pop(); } else { return false; } } } return stack.isEmpty(); } }
設計一個支援 push,pop,top 操作,並能在常數時間內檢索到最小元素的棧。
- push(x) -- 將元素 x 推入棧中。
- pop() -- 刪除棧頂的元素。
- top() -- 獲取棧頂元素。
- getMin() -- 檢索棧中的最小元素。
示例:
MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3. minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin(); --> 返回 -2.
class MinStack { /** initialize your data structure here. */ Stack<Integer> stack; Stack<Integer> minStack; /** initialize your data structure here. */ public MinStack() { stack = new Stack<Integer>(); minStack = new Stack<Integer>(); } public void push(int x) { if (minStack.isEmpty() || getMin() > x) { minStack.push(x); } else { minStack.push(getMin()); } stack.push(x); } public void pop() { if (!stack.isEmpty()) { stack.pop(); minStack.pop(); } } public int top() { return stack.peek(); } public int getMin() { return minStack.peek(); } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(x); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */
實現一個基本的計算器來計算一個簡單的字串表示式的值。
字串表示式可以包含左括號 (
,右括號 )
,加號 +
,減號 -
,非負整數和空格
。
示例 1:
輸入: "1 + 1" 輸出: 2
示例 2:
輸入: " 2-1 + 2 " 輸出: 3
示例 3:
輸入: "(1+(4+5+2)-3)+(6+8)" 輸出: 23
說明:
- 你可以假設所給定的表示式都是有效的。
- 請不要使用內建的庫函式
eval
。
public class Solution {
public int calculate(String s) {
if(s == null || s.length() == 0)
return 0;
s = "(" + s + ")";
Stack<Character> cstack = new Stack<Character>();
Stack<Integer> istack = new Stack<Integer>();
boolean isNum = false;
int sum = 0;
for(int i = 0 ; i < s.length() ; i++){
if(s.charAt(i) == ' ')
continue;
if(Character.isDigit(s.charAt(i))){
sum = sum *10 + s.charAt(i) - '0';
isNum = true;
continue;
}else if(isNum){ //考慮到會有 (( 連續的非數字情況 只需壓入一次數字
istack.push(sum);
sum = 0;
isNum = false;
}
if(s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '('){
cstack.push(s.charAt(i));
}else if(s.charAt(i) == ')'){
int temp = 0; // 每一次括號裡的值
while(cstack.peek() != '('){ //直到可以匹配的左括號
int a = istack.pop();
int c = cstack.pop();
if(c == '+'){
temp += a;
}else if(c == '-'){
temp -= a;
}
}
temp += istack.pop(); // 加上左括號後面的數字
istack.push(temp);
cstack.pop();
}
}
return istack.pop();
}
}
使用棧實現佇列的下列操作:
- push(x) -- 將一個元素放入佇列的尾部。
- pop() -- 從佇列首部移除元素。
- peek() -- 返回佇列首部的元素。
- empty() -- 返回佇列是否為空。
示例:
MyQueue queue = new MyQueue(); queue.push(1); queue.push(2); queue.peek(); // 返回 1 queue.pop(); // 返回 1 queue.empty(); // 返回 false
說明:
- 你只能使用標準的棧操作 -- 也就是隻有
push to top
,peek/pop from top
,size
, 和is empty
操作是合法的。 - 你所使用的語言也許不支援棧。你可以使用 list 或者 deque(雙端佇列)來模擬一個棧,只要是標準的棧操作即可。
- 假設所有操作都是有效的 (例如,一個空的佇列不會呼叫 pop 或者 peek 操作)。
class MyQueue {
Stack<Integer> stack;
Stack<Integer> reverseStack;
/** Initialize your data structure here. */
public MyQueue() {
stack = new Stack<>();
reverseStack = new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
while (!reverseStack.isEmpty()) {
stack.push(pop());
}
stack.push(x);
// Pure back
while (!stack.isEmpty()) {
reverseStack.push(stack.pop());
}
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
return reverseStack.pop();
}
/** Get the front element. */
public int peek() {
return reverseStack.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return reverseStack.isEmpty();
}
}
/**
* 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();
* boolean param_4 = obj.empty();
*/
給定兩個沒有重複元素的陣列 nums1
和 nums2
,其中nums1
是 nums2
的子集。找到 nums1
中每個元素在 nums2
中的下一個比其大的值。
nums1
中數字 x 的下一個更大元素是指 x 在 nums2
中對應位置的右邊的第一個比 x 大的元素。如果不存在,對應位置輸出-1。
示例 1:
輸入: nums1 = [4,1,2], nums2 = [1,3,4,2]. 輸出: [-1,3,-1] 解釋: 對於num1中的數字4,你無法在第二個陣列中找到下一個更大的數字,因此輸出 -1。 對於num1中的數字1,第二個陣列中數字1右邊的下一個較大數字是 3。 對於num1中的數字2,第二個陣列中沒有下一個更大的數字,因此輸出 -1。
示例 2:
輸入: nums1 = [2,4], nums2 = [1,2,3,4]. 輸出: [3,-1] 解釋: 對於num1中的數字2,第二個陣列中的下一個較大數字是3。 對於num1中的數字4,第二個陣列中沒有下一個更大的數字,因此輸出 -1。
注意:
nums1
和nums2
中所有元素是唯一的。nums1
和nums2
的陣列大小都不超過1000。
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int m = nums1.length, n = nums2.length;
int[] result = new int[m];
Map<Integer, Integer> pos = new HashMap<>();
for (int i = 0; i < n; i++) {
pos.put(nums2[i], i);
}
for (int i = 0; i < m; i++) {
result[i] = check(nums2, pos.get(nums1[i]), nums1[i]);
}
return result;
}
private int check(int[] nums, int index, int val) {
for (int i = index; i < nums.length; i++) {
if (nums[i] > val) return nums[i];
}
return -1;
}
}
給定 S
和 T
兩個字串,當它們分別被輸入到空白的文字編輯器後,判斷二者是否相等,並返回結果。 #
代表退格字元。
示例 1:
輸入:S = "ab#c", T = "ad#c" 輸出:true 解釋:S 和 T 都會變成 “ac”。
示例 2:
輸入:S = "ab##", T = "c#d#" 輸出:true 解釋:S 和 T 都會變成 “”。
示例 3:
輸入:S = "a##c", T = "#a#c" 輸出:true 解釋:S 和 T 都會變成 “c”。
示例 4:
輸入:S = "a#c", T = "b" 輸出:false 解釋:S 會變成 “c”,但 T 仍然是 “b”。
提示:
1 <= S.length <= 200
1 <= T.length <= 200
S
和T
只含有小寫字母以及字元'#'
。
class Solution {
public boolean backspaceCompare(String S, String T) {
if (S == null || T == null) return false;
return type(S).equals(type(T));
}
private String type(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '#') {
if (!stack.isEmpty()) stack.pop();
} else {
stack.push(c);
}
}
StringBuffer sb = new StringBuffer();
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
return sb.toString();
}
}