括号常考面试题

括号匹配

https://leetcode-cn.com/problems/valid-parentheses/

class Solution {
    public boolean isValid(String s) {
        if(s == null || s.length() == 0) {
            return false;
        }
        int len = s.length();
        for(int i = 0; i < len; i++) {
            s = s.replace("()","").replace("[]","").replace("{}","");
        }
        return s.length() == 0;
    }
}

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for(int i = 0; i < s.length();i++) {
           char  ch = s.charAt(i);
            if(ch == '{'||ch == '['||ch == '('){
                stack.push(ch);
            }else{
                if(stack.isEmpty()) {
                    return false;
                }
                char top = stack.peek();
                if(top == '{' && ch =='}' || top == '[' && ch ==']'|| top == '(' && ch ==')') {
                    stack.pop();
                }else {
                    return false;
                }
            }
        }
        if(stack.empty()) {
            return true;
        }
        return false;
    }
}

带*的括号匹配

https://leetcode-cn.com/problems/valid-parenthesis-string/

class Solution {
    //记录当前未匹配左括号数量的范围即可。只需遍历一遍,不需要使用栈。
    public boolean checkValidString(String s) {
        if(s == null || s.length() == 0) {
            return true;
        }
         int l = 0, r = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '(') {
                l++;
                r++;
            } else if (s.charAt(i) == ')') {
                l--;
                r--;
            } else {
                l--;
                r++;
            }
            if (r < 0) {
                return false;
            }
            if (l < 0) l = 0;
        }
        return l == 0;
    }
}


//双栈实现
class Solution {

    public boolean checkValidString(String s) {
        //存储左括号索引
        Stack<Integer> leftStack = new Stack<>();
        //存储*索引
        Stack<Integer> starStack = new Stack<>();
        
        int n = s.length();
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (c == '(') {
                leftStack.push(i);
            } else if (c == '*') {
                starStack.push(i);
            } else {
                if (!leftStack.isEmpty()) {
                    leftStack.pop();
                } else if (!starStack.isEmpty()) {
                    starStack.pop();
                } else {
                    return false;
                }
            }
        }
        while (!leftStack.isEmpty() && !starStack.isEmpty()) {
            
            //把*当成右括号,但是必须右括号的索引 > 左括号才能匹配
            //因为是栈结构,所以根据遍历,栈顶元素的索引是最大的索引,如果不满足就return false
            if (leftStack.pop() > starStack.pop()) {
                return false;
            }
        }
        return leftStack.isEmpty();
    }
}

括号生产(生成匹配的括号)

https://leetcode-cn.com/problems/generate-parentheses/
在这里插入图片描述

class Solution {
    List<String> ret = new ArrayList<>();
    public List<String> generateParenthesis(int n) {
        dfs(n, n, "");
        return ret;
    }

    private void dfs(int left, int right, String curStr) {
        if (left == 0 && right == 0) { // 左右括号都不剩余了,递归终止
            ret.add(curStr);
            return;
        }

        if (left > 0) { // 如果左括号还剩余的话,可以拼接左括号
            dfs(left - 1, right, curStr + "(");
        }
        if (right > left) { // 如果右括号剩余多于左括号剩余的话,可以拼接右括号
            dfs(left, right - 1, curStr + ")");
        }
    }
}

括号生成II(面试题)

在这里插入图片描述
https://leetcode-cn.com/problems/bracket-lcci/

class Solution {
    List<String> ret = new ArrayList<String>();
    public List<String> generateParenthesis(int n) {
        String s = "";
        int l = 0;
        int r = 0;
        dfs(n, s, l, r);
        return ret;
    }
    public void dfs(int n, String s, int l, int r){
        // 终止条件
        if(s.length() == 2 * n){
            ret.add(s);
            return ;
        }
        // l < n 则可添加左括号
        if(l < n){
            dfs(n, s + "(", l + 1, r);
        }
        // 如果该位置的右括号数目小于左括号 则可添加右括号
        if(r < l){
            dfs(n, s + ")", l, r + 1);
        }
    }
}

最长括号子串(dp)

import java.util.*;
public class Solution {
    public int longestValidParentheses (String s) {
        // write code here
        if (s == null || s.length() < 2) {
            return 0;
        }
        int[] f = new int[s.length()];
        if (s.charAt(0) == '(' && s.charAt(1) == ')') {
            f[1] = 2;
        }
        int ret = Math.max(f[1], 0);
        for (int i = 2; i < s.length(); i++) {
            if (s.charAt(i) == ')') {
                if (s.charAt(i - 1) == '(') {
                    f[i] = 2 + f[i - 2];
                } else {
                    int index = i - f[i - 1] - 1;
                    if (index >= 0 && s.charAt(index) == '(') {
                        f[i] = 2 + f[i - 1];
                        if (index - 1 >= 0) {
                            f[i] += f[index - 1];
                    }
                }
            }
        }
        ret = Math.max(ret, f[i]);
    }
    return ret;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值