每日三题-有效的括号、最长有效括号、最小栈

简介: 每日三题有效的括号最长有效括号最小栈

有效的括号


e9f2c84ed8ee417382a043d529558d8f.png解法一

使用保存符号的左边框

如果出现有边框就与栈顶符号进行匹配

如果匹配失败则return false

注意:对栈的使用要注意判空

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<Character>();
        for(int i  = 0;i < s.length();i++){
            char cur = s.charAt(i); // 当前字符
            if(cur == '[' || cur == '{' || cur == '(')stack.add(cur);
            else {
                if(stack.isEmpty()) return false; // 如果当前为空
                char t = stack.pop();
                if(cur == ']' && t != '[') return false;
                if(cur == ')' && t != '(') return false;
                if(cur == '}' && t != '{') return false;
            }
        }
        if(!stack.isEmpty()) return false;
        return true;
    }
}


最长有效括号


4d1dd6d0301a40d78cecfdac3e2bf17f.png

解法一

遍历

首先判断长度为len的字符串是否满足

然后判断长度为len-1的字符串是否满足

然后一直到判断长度为2的字符串是否满足

时间复杂度为(O(N^3))

class Solution {
    public int longestValidParentheses(String s) {
        int len = s.length();
        if(len <= 1 )return 0;
        for(int i = len-1;i >= 1;i--){ // 当前匹配字符串的长度
            for(int j = 0;j < len-i;j++){ //从哪里开始匹配
                if(isVaild(s,j,j+i)){
                    return i+1; // 因为i比长度少了1
                }
            }
        }
        return 0;
    }
    public Boolean isVaild(String s,int l,int r){
        Stack<Character> stack = new Stack<Character>();
        for(int i = l;i <= r;i++){
            if(s.charAt(i) == '(') stack.add(s.charAt(i));
            else {
                if(stack.isEmpty()) return false;
                if(stack.pop() != '(') return false; 
            }
        }
        return stack.isEmpty();
    }
}

解法二

使用

知世参考这位大佬的文章

class Solution {
    public int longestValidParentheses(String s) {
        int res = 0;
        Stack<Integer> stack = new Stack<Integer>();
        int start = 0;
        for(int i = 0;i < s.length();i++){
            if(s.charAt(i) == '(') stack.add(i);
            else{
                if(stack.isEmpty()){
                    start = i+1;
                }else{
                    stack.pop();
                    if(stack.isEmpty()){  // 说明从start-i都是匹配好的
                        res = Math.max(res,i-start+1);
                    }else{ // 说明现在的s.peek()后面 - i是匹配好的
                        res = Math.max(res,i-stack.peek());
                    }
                }
            }
        }
        return res;
    }
}

解法三

使用动态规划

这就是一个最值问题

设置dp[i] 为以s.charAt(i)结尾的字符串的最长有效括号的长度

所以当s.charAt(i)== '('时候,dp[i] = 0

**注意:**边界问题多判断是否到-1了

所以有下面几种情况

7cd047b3f8ce4976a5b0c36a25753afc.pngfe379d9264bc4d488bff4cbd4ac1619a.png1d5339d95ed0417f876e266bb47dda0a.png

class Solution {
    public int longestValidParentheses(String s) {
        int len = s.length();
        int res = 0;
        if(len <= 1) return 0;
        int dp[] = new int[len];  //dp[i] 表示以s.charAt(i) 结尾的字符串的长度
        for(int i = 1;i < len;i++){
            //s,charAt(i) == '('则为 0 
            if(s.charAt(i) == ')'){
                if(s.charAt(i-1) == '('){ // 说明是这种情况 ()()
                    dp[i] = (i-2>=0?dp[i-2]:0) + 2;
                }else if(i-dp[i-1] > 0 && s.charAt(i-dp[i-1]-1) == '('){
                    dp[i] = 2 + dp[i-1] + (i-dp[i-1]-2 >= 0 ?dp[i-dp[i-1]-2]:0);
                }
            }
            res = Math.max(res,dp[i]);
        }
        return res;
    }
}

解法四

使用left保存左括号的数量

使用right保存右括号的数量

如果left < right 说明右括号多了,说明这里已经与后面的断开了,后面的不会在这里以及前面的存在匹配直接left == right ==0

如果left == right,那么这时候匹配的长度就是2 * right

但是存在可能left 一直 大于right,那么这样就可以从后往前遍历解决问题

class Solution {
    public int longestValidParentheses(String s) {
        int res = 0;
        int left = 0,right = 0;
        for(int i = 0;i < s.length();i++){
            if(s.charAt(i) == '('){
                left++;
            }else{
                right++;
            }
            if(left == right){
                res = Math.max(res,2*right);
            }
            if(left < right){
                left = right = 0;
            }
        }
        left = right = 0;
        for(int i = s.length()-1;i >= 0;i--){
            if(s.charAt(i) == ')'){
                left++;
            }else{
                right++;
            }
            if(left == right){
                res = Math.max(res,2*right);
            }
            if(left < right){
                left = right = 0;
            }
        }
        return res;
    }
}


最小栈


解法一

额外维护一个最小栈

class MinStack {
    Stack<Integer> s1 = null;
    Stack<Integer> min = null;
    public MinStack() {
        s1 = new Stack<Integer>();
        min = new Stack<Integer>();
    }
    public void push(int val) {
        s1.add(val);
        if(min.isEmpty()){
            min.add(val);
        }else{
            int t = min.peek();
            min.add(t > val?val:t);
        }
    }
    public void pop() {
        s1.pop();
        min.pop();
    }
    public int top() {
        return s1.peek();
    }
    public int getMin() {
        return min.peek();
    }
}
相关文章
|
22天前
|
算法 测试技术 C++
【贪心 堆 】3081. 替换字符串中的问号使分数最小
【贪心 堆 】3081. 替换字符串中的问号使分数最小
|
22天前
LeetCode题 338比特位计数,20有效的括号,415字符串相加
LeetCode题 338比特位计数,20有效的括号,415字符串相加
41 0
|
22天前
|
Java Go C++
C/C++每日一练(20230424) 只出现一次的数字、有效的括号、递归反序正整数
C/C++每日一练(20230424) 只出现一次的数字、有效的括号、递归反序正整数
32 0
C/C++每日一练(20230424) 只出现一次的数字、有效的括号、递归反序正整数
|
22天前
|
Python Java Go
Python每日一练(20230428) 最长有效括号、矩阵最长递增路径、回文链表
Python每日一练(20230428) 最长有效括号、矩阵最长递增路径、回文链表
36 0
Python每日一练(20230428) 最长有效括号、矩阵最长递增路径、回文链表
|
11月前
|
C语言
C语言:杨氏矩阵中查找某数(时间复杂度小于O(N))
题目: 有一个数字矩阵(二维数组), 矩阵的每行从左到右是递增的, 矩阵从上到下是递增的, 请编写程序在这样的矩阵中查找某个数字是否存在, 要求:时间复杂度小于O(N)。
234 1
|
8月前
|
C语言
【Leetcode-1574.删除最短的子数组使剩余数组有序(C语言)】
【Leetcode-1574.删除最短的子数组使剩余数组有序(C语言)】
23 0
LeetCode-32 最长有效括号
LeetCode-32 最长有效括号
|
11月前
|
Go Cloud Native
856. 括号的分数:栈的思想
这是 力扣上的 856. 括号的分数:,难度为 中等。
856. 括号的分数:栈的思想
leetcode-32. 最长有效括号(堆栈+贪心)
左边出现多余的括号, ‘ ) ’我们不用担心,我们已经算匹配完,用mark记录就行,‘ ( ’的话我们只需要先记录在堆栈里,再循环结束后,将多余的没有匹配的’ ( '一一用mark记录
67 0
leetcode-32. 最长有效括号(堆栈+贪心)
|
算法 Python
Acwing 771.双指针 字符串中最长的连续出现的字符
Acwing 771.双指针 字符串中最长的连续出现的字符
70 0

热门文章

最新文章