合法括号序列
合法括號序列需要滿足:
- 左右括號數量相同
- 任意一個前綴中,左括號數量≥右括號數量
題目:leetcode301.刪除無效的括號
????????給你一個由若干括號和字母組成的字符串?s?,刪除最小數量的無效括號,使得輸入的字符串有效。
????????返回所有可能的結果。答案可以按?任意順序?返回。
思路:首先根據合法序列要求求出需要刪除的左括號數量和右括號數量。然后進行dfs刪除多余的左右括號。為確保處理后的字符串滿足左右括號數量相同,需要另一個參數cnt。當有連續的左右括號需要刪除時,首先求出連續的左右括號數量,然后直接判斷將連續的左右括號全部刪完是否≤需要刪除的左右括號數量,滿足的話,直接刪除,否則少刪除一個左右括號,依次循環。
代碼:
class Solution {List<String> res = new ArrayList<>();public List<String> removeInvalidParentheses(String s) {int n = s.length();int l = 0,r = 0;for(int i = 0;i < n;i++) { //統計需要刪除的左右括號數量char c = s.charAt(i);if(c == '(') {l++;} else if(c == ')') {if(l == 0) {r++;} else {l--;}}}dfs(s,0,"",0,l,r); // 第一個0是字符串索引,第二個0是path左右括號數量差值return res;}public void dfs(String s,int u,String path,int cnt,int l,int r) {if(u == s.length()) {if(cnt == 0) {res.add(path);}return;}char c = s.charAt(u);if(c == '(') {int k = u;while(k < s.length() && s.charAt(k) == '(') { // 統計連續的左括號數量k++;}l -= k - u;for(int i = k - u;i >= 0;i--) { // i是刪除的左括號數量if(l >= 0) {dfs(s,k,path,cnt,l,r);}path += '(';l++;cnt++;}} else if(c == ')') {int k = u;while(k < s.length() && s.charAt(k) == ')') { // 統計連續的右括號數量k++;}r -= k - u;for(int i = k - u;i >= 0;i--) { // i是刪除的右括號數量if(cnt >= 0 && r >= 0) {dfs(s,k,path,cnt,l,r);}path += ')';r++;cnt--;}} else {dfs(s,u+1,path+s.charAt(u),cnt,l,r);}} }題目:leetcode32. 最長括號序列
給你一個只包含?'('?和?')'?的字符串,找出最長有效(格式正確且連續)括號子串的長度。
提示:
- 0 <= s.length <= 3 * 104
- s[i]?為?'('?或?')'
思路:(棧)首先需要一個分隔符start,分隔一個個區間,不同區間之間不可能結合在一起形成新的合法括號序列。
????????證明:每個區間滿足任意前綴中左括號數量大于等于右括號數量,并且最后一個是‘)’,使得右括號數量比左括號數量多一。a區間s[i,j],b區間s[j+1,k],將其合并成c區間s[u,p],其中s[u,j]是屬于a區間的,該區間必然滿足右括號數量大于左括號數量,所以直接不滿足合法括號序列的要求。
從頭到尾遍歷字符串,當遇到‘(’時,將其序號壓入棧中;當遇到‘)’時,判斷棧中是否存在元素,如果存在元素,先將其彈出,彈出后棧為空,那么此時的合法序列長度為i-start,否則合法序列長度為i-stk.peek()(此時stk.peek()是最近的一個未被匹配的左括號)。棧中不存在元素時,那么此時i作為一個新的分隔符,start=i。
class Solution {public int longestValidParentheses(String s) {Stack<Integer> stk = new Stack<>();int res = 0;for(int i = 0, start = -1;i < s.length();i++) {if(s.charAt(i) == '(') {stk.push(i);} else {if(stk.size() > 0) {stk.pop();if(stk.size() == 0) {res = Math.max(res,i-start);} else {res = Math.max(res,i-stk.peek());}} else {start = i;}}}return res;} }總結
- 上一篇: java高级类_Java高级类特性(一)
- 下一篇: 数学手册|赋范空间概念