请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
- 示例 1:
-
- 输入:
- ["MyQueue", "push", "push", "peek", "pop", "empty"]
- [[], [1], [2], [], [], []]
- 输出:
- [null, null, null, 1, 1, false]
-
- 解释:
- MyQueue myQueue = new MyQueue();
- myQueue.push(1); // queue is: [1]
- myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
- myQueue.peek(); // return 1
- myQueue.pop(); // return 1, queue is [2]
- myQueue.empty(); // return false
- class MyQueue {
- Stack
stackIn; - Stack
stackOut; -
- public MyQueue() {
- stackIn=new Stack<>();
- stackOut=new Stack<>();
- }
-
- public void push(int x) {
- stackIn.push(x);
- }
-
- public int pop() {
- inToOut();
- return stackOut.pop();
- }
-
- public int peek() {
- inToOut();
- return stackOut.peek();
- }
-
- public boolean empty() {
- return stackIn.isEmpty()&&stackOut.isEmpty();
- }
- public void inToOut(){
- if(!stackOut.isEmpty()) return;
-
- while(!stackIn.isEmpty()){
- stackOut.push(stackIn.pop());
- }
- }
- }
-
- /**
- * 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();
- */
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
- class MyStack {
- Deque
queue; -
- public MyStack() {
- queue=new ArrayDeque<>();
-
- }
-
- public void push(int x) {
- queue.addLast(x);
- }
-
- public int pop() {
- int size=queue.size();
- size--;
- while(size-->0){
- queue.addLast(queue.poll());
- }
- int res=queue.pollFirst();
- return res;
- }
-
- public int top() {
- return queue.peekLast();
-
- }
-
- public boolean empty() {
- return queue.isEmpty();
- }
- }
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
- 示例 1:
-
- 输入:s = "()"
- 输出:true
- 示例 2:
-
- 输入:s = "()[]{}"
- 输出:true
- 示例 3:
-
- 输入:s = "(]"
- 输出:false
- 示例 4:
-
- 输入:s = "([)]"
- 输出:false
- 示例 5:
-
- 输入:s = "{[]}"
- 输出:true
- //方法1 map
- class Solution {
- public boolean isValid(String s) {
- Map
map=new HashMap<>(); - Stack
stack=new Stack<>(); - map.put(')','(');
- map.put(']','[');
- map.put('}','{');
-
- for(char ch:s.toCharArray()){
- if(!map.containsKey(ch)){
- stack.push(ch);
- }else{
- if(stack.isEmpty()||!map.get(ch).equals(stack.peek())){
- return false;
- }else{
- stack.pop();
- }
-
- }
- }
- if(stack.isEmpty()){
- return true;
- }
- return false;
- }
- }
-
- //方法2
- class Solution {
- public boolean isValid(String s) {
- Stack
stack=new Stack<>(); -
- for(char ch:s.toCharArray()){
- if(ch=='('){
- stack.push(')');
- }else if(ch=='['){
- stack.push(']');
- }else if(ch=='{'){
- stack.push('}');
- }else{
- if(!stack.isEmpty()&&ch==stack.peek()){
- stack.pop();
- }else{
- return false;
- }
- }
- }
- return stack.isEmpty();
- }
- }
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
- 示例:
-
- 输入:"abbaca"
- 输出:"ca"
- 解释:
- 例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
-
- class Solution {
- public String removeDuplicates(String S) {
- StringBuilder sb=new StringBuilder();
- Stack
stack=new Stack<>(); -
- for(char ch:s.charArray()){
-
- if(stack.isEmpty()||stack.peek()!=ch){
- stack.push(ch);
-
- }else{
- stack.pop();
-
- }
- }
- for(int i=stack.size();i>=0;i--){
- sb.append(stack.pop());
- }
- return sb.toString();
- }
- }
根据 逆波兰表示法,求表达式的值。
有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
- 示例 1:
-
- 输入:tokens = ["2","1","+","3","*"]
- 输出:9
- 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
- 示例 2:
-
- 输入:tokens = ["4","13","5","/","+"]
- 输出:6
- 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
- 示例 3:
-
- 输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
- 输出:22
- 解释:该算式转化为常见的中缀算术表达式为:
- ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
- = ((10 * (6 / (12 * -11))) + 17) + 5
- = ((10 * (6 / -132)) + 17) + 5
- = ((10 * 0) + 17) + 5
- = (0 + 17) + 5
- = 17 + 5
- = 22
-
- class Solution {
- public int evalRPN(String[] tokens) {
- int res=0;
- Deque
stack=new ArrayDeque<>(); -
- for(int i=0;i
- if("+".equals(tokens[i])){
- res=stack.pop()+stack.pop();
- stack.push(res);
- }else if("-".equals(tokens[i])){
- res=-stack.pop()+stack.pop();
- stack.push(res);
- }else if("*".equals(tokens[i])){
- res=stack.pop()*stack.pop();
- stack.push(res);
- }else if("/".equals(tokens[i])){
- int num1=stack.pop();
- int num2=stack.pop();
- res=num2/num1;
- stack.push(res);
- }else{
- stack.push(Integer.valueOf(tokens[i]));
- }
- }
- return stack.pop();
- }
- }
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
- 示例 1:
-
- 输入: nums = [1,1,1,2,2,3], k = 2
- 输出: [1,2]
- 示例 2:
-
- 输入: nums = [1], k = 1
- 输出: [1]
-
- //大顶堆
- class Solution {
- public int[] topKFrequent(int[] nums, int k) {
- Map
map=new HashMap<>(); -
- for(int num:nums){
- map.put(num,map.getOrDefault(num,0)+1);
- }
-
- PriorityQueue
> queue=new PriorityQueue<>((o1,o2)->o2.getValue()-o1.getValue()); -
- for(Map.Entry
entry:map.entrySet()){ - queue.offer(entry);
- }
-
- int[] res=new int[k];
- for(int i=k-1;i>=0;i--){
- res[i]=queue.poll().getKey();
- }
-
- return res;
- }
- }
-
- //小顶堆
- class Solution {
- public int[] topKFrequent(int[] nums, int k) {
- Map
map=new HashMap<>(); -
- for(int num:nums){
- map.put(num,map.getOrDefault(num,0)+1);
- }
-
- PriorityQueue
> queue=new PriorityQueue<>((o1,o2)->o1.getValue()-o2.getValue()); -
- for(Map.Entry
entry:map.entrySet()){ - queue.offer(entry);
- if(queue.size()>k){
- queue.pop();
- }
- }
-
- int[] res=new int[k];
- for(int i=k-1;i>=0;i--){
- res[i]=queue.poll().getKey();
- }
-
- return res;
- }
- }