ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LeetCode刷题301.删除无效括号

2021-10-27 17:33:11  阅读:194  来源: 互联网

标签:right int 301 括号 rightDelete leftDelete left LeetCode 刷题


301.删除无效括号

给定一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。返回所有可能的结果。答案可以按 任意顺序 返回。
示例1:

输入:s = “()())()”
输出:["(())()","()()()"]

示例2:

输入:s = “(a)())()”
输出:["(a())()","(a)()()"]

示例3:

输入:s = “)(”
输出:[""]

思路:对于每个左括号,都有一个对应的右括号。我们可以使用两个计数器来跟踪错位的左括号和右括号,在一次迭代中,我们可以找到这两个值。
例如:
Alt
i = 0, left = 1, right = 0
i = 1, left = 0, right = 0
i = 2, left = 0, right = 1
i = 3, left = 0, right = 2
i = 4, left = 1, right = 2
i = 5, left = 2, right = 2
i = 6, left = 3, right = 2
i = 7, left = 2, right = 2

根据最后结果显示,有两个错放的左括号和两个错放的右括号。
因此,其基本思路可以概括为:
1、计算需要去除的括号数;
2、回溯,将leftDelete和rightDelete降为0;
3、判断s是否有效。
判断方法:把括号压栈,如果是有效括号“()”,就统一弹栈,如果一直有效,栈为空,则s有效,如果是“)(”,栈不为空,就是s无效。
代码:

class Solution {
	StringBuilder sb = new StringBuilder();
	Set<String> res = new HashSet<>();

	public List<String> removeInvalidParentheses(String s) {
		int leftDelete = 0;
		int rightDelete = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) == '(') {
				leftDelete++;
			} else if (s.charAt(i) == ')') {
				rightDelete = leftDelete == 0 ? rightDelete + 1 : rightDelete;
				leftDelete = leftDelete > 0 ? leftDelete - 1 : leftDelete;
			}
		}
		helper(s, 0, 0, 0, leftDelete, rightDelete);
		return new ArrayList<>(res);
	}

	public void helper(String s, int index, int numOfLeft, int numOfRight, int leftDelete, int rightDelete) {
		// 已经遍历到字符串尾部
		if (index == s.length()) {
			if (leftDelete == 0 && rightDelete == 0)
				res.add(sb.toString());

		} else if (numOfRight > numOfLeft) {
			return;
		} else {
			char c = s.charAt(index);
			// 优先不添加括号
			if ((c == '(' && leftDelete > 0) || (c == ')' && rightDelete > 0)) {
				helper(s, index + 1, numOfLeft, numOfRight, leftDelete - (c == '(' ? 1 : 0),
						rightDelete - (c == ')' ? 1 : 0));
			}
			sb.append(c);
			if (c != '(' && c != ')') {
				helper(s, index + 1, numOfLeft, numOfRight, leftDelete, rightDelete);
			} else if (c == '(') {
				helper(s, index + 1, numOfLeft + 1, numOfRight, leftDelete, rightDelete);
			} else {
				helper(s, index + 1, numOfLeft, numOfRight + 1, leftDelete, rightDelete);
			}
			sb.deleteCharAt(sb.length() - 1);
		}
	}
}

执行结果:
Alt
总结: LeetCode第一天打卡就遇到了困难的题,在看到题后就有了想放弃的想法,但是还是坚持一步步的去理解题目,理清思路,虽然代码是在看视频查资料后完成的,但还是收获了很多,对自己的代码能力的提升有很大的帮助。

标签:right,int,301,括号,rightDelete,leftDelete,left,LeetCode,刷题
来源: https://blog.csdn.net/weixin_46566527/article/details/120995944

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有