44 有效括号序列
很容易想到用栈,但是一开始还是写得有问题
import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @return bool布尔型
*/
public boolean isValid (String s) {
// write code here
Stack<Character> st = new Stack<>();
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if(c=='['||c=='('||c=='{'){
st.push(c);
}else if(st.isEmpty()){
return false;//右括号数量更多
}else if(c==']'){
if(st.pop()!='[') return false;
}else if(c==')'){
if(st.pop()!='(') return false;
}else if(c=='}'){
if(st.pop()!='{') return false;
}
}
if(!st.isEmpty()){//左括号数量更多
return false;
}
else return true;
}
}
可以用Stack<Character> st,一开始以为不能用Char,用字符串存的话需要转换,可以用String.ValueOf©来将char转换为String
用string来存调了半天的bug!!!因为字符串不能用==来判断是否相等!!!要用equals方法!!!
import java.util.*;
public class Solution {
/**
*
* @param s string字符串
* @return bool布尔型
*/
public boolean isValid (String s) {
// write code here
Stack<String> st = new Stack<>();
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if(c=='['||c=='('||c=='{'){
st.push(String.valueOf(c));
}else if(st.isEmpty()){
return false;//右括号数量更多
}else if(c==']'){
if(!st.pop().equals("[")) return false;
}else if(c==')'){//!!!!!不能用!=来判断!!!
if(!st.pop().equals("(")) return false;
}else if(c=='}'){
if(!st.pop().equals("{")) return false;
}
}
if(!st.isEmpty()){//左括号数量更多
return false;
}
else return true;
}
}
45 滑动窗口的最大值
第一眼的想法是想像43题那样直接根据滑出和进入的比较,但是发现不可能的原因是43题的最小值永远是递减的,因为是栈的结构,之前在的会一直在,最差也是push和上次一样的值,但是这题就不行,相当于队列的结构,push的最大值是没有规律而言的。最简单的做法就是每次在窗口里判断最大值,这样时间复杂度是O(n*size),空间复杂度是O(1),存结果必须要开的数组不算入额外空间.不符合题目要求
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size) {
if(num.length<size||size==0) return new ArrayList<>();
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i+size-1<num.length;i++){
int max = Integer.MIN_VALUE;
for(int j=i;j<i+size;j++){
if(num[j]>max) max = num[j];
}
list.add(max);
}
return list;
}
}
看了题解之后才懂了双端队列的做法:
- 用双端对列q存index,假设队列左边为first,右边为last,每滑动一个窗口需要如下操作:
- 每当当前数据要从last进入,要先把在队列中的且更小的元素poll出去,因为之前的数据更小,永远都没用了。
- 根据下标判断窗口外的过期数据,在first端poll出去
- 根据第一步,队列中的数据是非递增的,first端是最大的,把first的数据加入队列中即可
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size) {
if(num.length<size||size==0) return new ArrayList<>();
ArrayList<Integer> list = new ArrayList<>();
ArrayDeque<Integer> q = new ArrayDeque<>();
int max = Integer.MIN_VALUE;
int index=0;
for(int end=0;end<num.length;end++){
while(!q.isEmpty()&&num[q.peekLast()]<num[end]){
q.pollLast();//去掉在新加入元素前面的且更小的
}
q.addLast(end);
while(!q.isEmpty()&&q.peekFirst()<=end-size){
q.pollFirst();//去掉窗口外的
}
if(end>=size-1)list.add(num[q.peekFirst()]);//前size个只要存一个
}
return list;
}
}
这样时间复杂度O(n),空间复杂度O(size)