一、20. 有效的括号
1.题目
https://leetcode-cn.com/problems/valid-parentheses/
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
2.思路
1.仅用栈 遍历一遍,如果是符号左边那么push 符号的右边。根据栈先进后出的原理,如果遍历字符是右括号,那需要看下是否等于栈顶元素,最后判断栈是否为空
注意:
(1)这里要先判断栈是否为空,再判断是否等于栈顶元素
(2)char 和array在java中
- 定义
char 在java中是16位的,是表示的是字符,定义的时候用单引号,只能存储一个字符。eg:char=‘d’.
string 在java中是unicode,表示的是字符串,定义的时候用双引号,可以存储一个或者多个字符。 eg:String=“we are neuer” - 转换
char是基本数据类型,而String 是一个类,具有面向对象的特征,可以调用方法,如name.length()获取字符串的长度
char转换为string的方法有:
·使用String.charAt(index)(返回值为char)可以得到String中某一指定位置的char
· 使用String.toCharArray()(返回值为char[])可以得到将包含整个String的char数组。这样我们就能够使用从0开始的位置索引来访问string中的任意位置的元素。
3.代码
class Solution {
public boolean isValid(String s) {
Stack <Character> stack = new Stack<>();
for (char c : s.toCharArray()){
if (c == '{') stack.push('}');
if (c == '(') stack.push(')');
if (c == '[') stack.push(']');
if (c == ']' || c == '}' || c==')'){
if(stack.isEmpty() || c != stack.peek()){
return false;
}else{
stack.pop();
}
}
}
return stack.isEmpty();
}
}
二、496.下一个更大元素 I
1.题目
给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。
请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。
https://leetcode-cn.com/problems/next-greater-element-i/
2.思路
典型的单调栈的思想(注意条件,nums1是nums2的子集)
1.找到比nums1中的大的数;
从后往前遍历nums2,输出单调递增的栈
2.存储起来
根据不重复的特性,可用map存储,key为具体的值,value为栈顶元素和key的关系
3.代码
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
// 单调栈
Map<Integer,Integer> map = new HashMap<>();
Stack<Integer> stack= new Stack<>();
//int num;
for(int i =nums2.length-1; i>=0;--i){
int num = nums2[i];
while(!stack.isEmpty() && nums2[i]>= stack.peek()){
stack.pop();
}
map.put(num,stack.isEmpty()?-1:stack.peek());
stack.push(num);
}
int [] res = new int [nums1.length];
for(int j = 0; j<nums1.length;j++){
res[j]=map.get(nums1[j]);
}
return res;
}
}
//判断温度升高问题也可用这个方法
https://leetcode-cn.com/problems/next-greater-element-i/solution/dan-diao-zhan-jie-jue-next-greater-number-yi-lei-w/
三、232 用栈实现队列
1.题目
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
2.思路
注意入队中间有出队的情况
3.代码
class MyQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public MyQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public void push(int x) {
stack1.push(x);
}
public int pop() {
if (stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
public int peek() {
if (stack2.isEmpty()){
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.peek();
}
public boolean empty() {
return stack2.isEmpty() && stack1.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();
*/