zoukankan      html  css  js  c++  java
  • [LeetCode]301. 删除无效的括号(DFS)

    题目

    题解

    • step1. 遍历一遍,维护left、right计数器,分别记录不合法的左括号、右括号数量.

      • 判断不合法的方法?
        • left维护未匹配左括号数量(增,减)(当left为0遇到右括号,则交由right处理),最终剩余的左括号数量就是不合法的左括号数量
        • 遇右括号时,若左侧的左括号都已被匹配(left==0),则此右括号为不合法右括号,right++
        • PS 对于题目中最少:此方法判断出的所有不合法括号,就是所谓的最少不合法括号数量;在此基础上得到的合理表达式,删除成对的括号,也会是合法表达式。
        • PS 为什么不同于判断合法括号的题目,只使用一个left计数器? 因为要对不合法的左括号和右括号分别记录数量.
    • step2.利用dfs不断删除"("或者")",直到不合法个数为0。参照相关中的步骤:

      1. dfs参数有:当前删除已删除括号后的字符串,待处理位置,剩余不合法左括号数l,剩余右括号不合法数r;
      2. 特别判断:去重:若当前字符和之前字符相同,则continue;
      3. 返回条件:l0&&r0,且当前字符串括号合法
      4. 删除当前括号,进入下一层搜索
    • step3.检验删除后的括号串是否合法。
      使用left计数器判断即可。

    • 注意: 当前还有不合法左(右)括号且当前括号为左(右)括号,才能进入下一层搜索。

    • 注意:下一层搜索的第一个参数

    相关

    判断括号有效:

    • 法1 (单一种类括号):维护left计数器
    • 法2 (多种类括号):使用栈

    dfs关键:

    1. dfs参数
    2. 一些特别的剪枝条件,根据情况选择直接返回或者continue
    3. dfs返回条件并返回,同时可能需要记录一些需要的结果
    4. 进入下层搜索的条件

    String:

    str1.subString(beg,end); //拷贝
    str2.subStr(beg,len); //拷贝
    

    代码

    class Solution {
        private List<String> validStrList;
    
    	public List<String> removeInvalidParentheses(String s) {
    		// 得到不合法左括号数和右括号数
    		int lCnt = 0;
    		int rCnt = 0;
    		for (int i = 0; i < s.length(); ++i) {
    			if (s.charAt(i) == '(') {
    				lCnt++;
    			} else if (s.charAt(i) == ')') {
    				if (lCnt > 0) {
    					lCnt--;
    				} else {
    					rCnt++;
    				}
    			}
    		}
    
    		validStrList = new ArrayList<>();
    		dfs(s, 0, lCnt, rCnt);
    		return validStrList;
    	}
    
    	private void dfs(String s, int pos, int lCnt, int rCnt) {
    		if (lCnt == 0 && rCnt == 0) {
    			if (validStr(s)) {
    				validStrList.add(s);
    			}
    			return;
    		}
    		for (int i = pos; i < s.length(); ++i) {
    			if (i != pos && s.charAt(i) == s.charAt(i - 1)) {
    				continue;
    			}
    			if (lCnt > 0 && s.charAt(i) == '(') {//
    				dfs(s.substring(0, i) + s.substring(i + 1), i, lCnt - 1, rCnt);//
    			}
    			if (rCnt > 0 && s.charAt(i) == ')') {//
    				dfs(s.substring(0, i) + s.substring(i + 1), i, lCnt, rCnt - 1);//
    			}
    		}
    	}
    
    	private boolean validStr(String s) {
    		int left = 0;
    		for (int i = 0; i < s.length(); ++i) {
    			if (s.charAt(i) == '(') {
    				left++;
    			} else if (s.charAt(i) == ')') {
    				if (left <= 0) {
    					return false;
    				}
    				left--;
    			}
    		}
    		return left == 0;
    	}
    }
    
  • 相关阅读:
    快速排序的分析与优化
    矩阵原地转置
    变位词问题
    一维向量旋转算法
    位图排序
    Linux网络编程:UDP实现可靠的文件传输
    Linux网络编程:UDP Socket编程范例
    es6+最佳入门实践(6)
    es6+最佳入门实践(5)
    es6+最佳入门实践(4)
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/12239828.html
Copyright © 2011-2022 走看看