20. 有效的括号
题意
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号
题解
实际上就是一个简单的栈的数据结构的实现,我们都知道,栈是先进后出的,那么我们假设现在的括号为(()),先放入(在栈底,在拿到(发现跟前面不匹配,继续放入,然后拿到)发现跟栈顶元素相同,pop()一下,记住如果当前不匹配,可以直接return false,因为之后不可能会有元素会匹配),继续拿到最后一个元素) ,跟栈顶对比,pop即可
代码
import java.util.*;
public class Solution {
public static void main(String[] args) {
}
public static boolean isValid(String s) {
char []arr=s.toCharArray();
Deque<Character> stack =new LinkedList<>();
for(int i=0;i<arr.length;i++){
if(arr[i]=='('||arr[i]=='['||arr[i]=='{'){
stack.push(arr[i]);
}
else if(stack.isEmpty()){
return false;
}
else{
char c=stack.peek();
if(arr[i]==')'){
if(c!='('){
return false;
}
stack.pop();
}
else if(arr[i]=='}'){
if(c!='{'){
return false;
}
stack.pop();
}
else if(arr[i]==']'){
if(c!='['){
return false;
}
stack.pop();
}
}
}
if(stack.size()!=0){
return false;
}
return true;
}
}
155. 最小栈
题意
设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
思路
刚开始以为需要自己实现栈来着,但是发现deque实现栈的时间复杂度本来就是o(1),那就直接用内置的即可,发现上面的所有操作,除了getMin()以外,剩下的都可以简单的实现,那么我们去思考一下如何动态的求一个最小值,其实也是比较简单,我们假设现在栈里有1 2 3 那么最小的元素是不是1 那么对于1后面的位置,你是不是可以忽略不记,因为没有价值,你可以将其全部初始化为1,也就是1 1 1,思路到位,那么,我们建立一个辅助栈,每一次放入最小值即可
代码
import java.util.*;
class MinStack {
Deque<Integer> arr1;
Deque<Integer> arr2;
public MinStack() {
arr1=new LinkedList<>();
arr2=new LinkedList<>();
arr2.push(Integer.MAX_VALUE);
}
public void push(int val) {
arr1.push(val);
arr2.push(Math.min(val,arr2.peek()));
}
public void pop() {
arr1.pop();
arr2.pop();
}
public int top() {
return arr1.peek();
}
public int getMin() {
return arr2.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
394. 字符串解码
题意
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string]
,表示其中方括号内部的 encoded_string
正好重复 k
次。注意 k
保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k
,例如不会出现像 3a
或 2[4]
的输入。
题解
思路比较简单,跟括号序列一样,遇到】的时候,去找到左边的与他最近的[,记录里面的字符串,然后看看前面的数字即可
代码
import java.util.*;
public class Solution {
public static void main(String[] args) {
}
public String decodeString(String s) {
Deque<Character> dp =new LinkedList<>();
char []arr=s.toCharArray();
String ans="";
for(int i=0;i<arr.length;i++){
char now=arr[i];
if(now>='0'&&now<='9'){
dp.push(now);
}
else{
if(now!=']'){
dp.push(now);
}
else{
String s3="";
while(dp.peek()!='['){
s3=dp.peek()+s3;
dp.pop();
}
dp.pop();
String s4="";
while(dp.size()>0&&dp.peek()>='0'&&dp.peek()<='9'){
s4=dp.peek()+s4;
dp.pop();
}
int f=0;
for(int j=0;j<s4.length();j++){
int x=s4.charAt(j)-'0';
f=f*10+x;
}
for(int j=0;j<f;j++){
for(int k=0;k<s3.length();k++){
dp.push(s3.charAt(k));
}
}
}
}
}
while(dp.size()>0){
ans=dp.peek()+ans;
dp.pop();
}
return ans;
}
}
739. 每日温度
题意
给定一个整数数组 temperatures
,表示每天的温度,返回一个数组 answer
,其中 answer[i]
是指对于第 i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0
来代替。
题解
题目的意思实际上就是去找后面第一个>他本身的第一个数字的位置,我们举个例子你就明白了,对于1 2 3 1 3 对于前面的2,后面的第一个>他的明显是第一个3,那么为什么不是第二个,以为3==3,也就是说如果我们从后往前遍历的话,如果当前元素>=后面的某个元素,那么后面的某个元素是没有价值的,因为被前面给覆盖了,明白这一点之后问题就解决了
代码
import java.util.*;
public class Solution {
public static void main(String[] args) {
int []arr={73,74,75,71,69,72,76,73};
dailyTemperatures(arr);
}
public static int[] dailyTemperatures(int[] temperatures) {
int []ans=new int[temperatures.length];
Deque<Integer> stack=new LinkedList<>();
for(int i=temperatures.length-1;i>=0;i--){
int x=temperatures[i];
while(stack.size()>0&&temperatures[stack.peek()]<=x){
stack.pop();
}
if(stack.size()==0){
stack.push(i);
}
else {
ans[i]=stack.peek()-i;
stack.push(i);
}
}
return ans;
}
}
84. 柱状图中最大的矩形
题意
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。 具体题目可以点击链接跳转
题解
其实跟上面的题意差不多,我们首先要明白一点,栈的题目一定是对于当前位置的数字前面的元素一定是某些位置没有了价值才能pop,也就是实现一个类似与单调性的问题,相对而言,我们当前问题,当前元素如果想要进行填满,那么是不是前面的元素要>他才可以,那么根据这个思路模拟即可,每一次求取左端的最大值以及len即可
代码
import java.util.*;
public class Solution {
public static void main(String[] args) {
}
public int largestRectangleArea(int[] heights) {
int maxx=0;
Deque<Integer> dp =new LinkedList<>();
for(int i=0;i<=heights.length;i++){
int x=(i==heights.length)? 0 :heights[i];
while(dp.size()>0&&x<heights[dp.peek()]){
int height = heights[dp.peek()];
dp.pop();
int len=dp.size()==0 ? i:i-dp.peek()-1;
maxx=Math.max(len*height,maxx);
}
dp.push(i);
}
return maxx;
}
}