死磕有效括號

2021-10-06 23:36:40 字數 3802 閱讀 8209

目錄

1、leetcode20. 有效的括號

2、leetcode22. 括號生成

3、leetcode32. 最長有效括號

3.1、滑動視窗暴力破解

3.2、借助棧

3.3、動態規劃

給定乙個只包括 '(',')','','[',']'?的字串,判斷字串是否有效。

有效字串需滿足:

左括號必須用相同型別的右括號閉合。

左括號必須以正確的順序閉合。

注意空字串可被認為是有效字串。

示例 1:

輸入: "()"

輸出: true

示例 2:

輸入: "(){}"

輸出: true

示例 3:

輸入: "(]"

輸出: false

示例 4:

輸入: "([)]"

輸出: false

示例 5:

輸入: ""

輸出: true

思路:利用棧的特性解決問題

public boolean isvalid(string s) 

stackstack = new stack<>();

for(int i=0;i數字 n 代表生成括號的對數,請你設計乙個函式,用於能夠生成所有可能的並且有效的括號組合。

示例:輸入:n = 3

輸出:[

"((()))",

"(()())",

"(())()",

"()(())",

"()()()"

]

思路:

1、回溯法

2、依次在將要生成的字串位置上放置 '(' 、')'

3、放完判斷字串是否為有效括號

4、利用左括號、右括號的數量相等剪枝。

public listgenerateparenthesis(int n) 

listlist = new arraylist<>();

generateparenthesis(new char[n*2],0,n,n,list);

return list;

}public void generateparenthesis(char strs,int index,int left,int right,listlist)

}else if(left == 0)else if(right == 0)else

}public boolean isvaild(char strs)elseelse

}} if(balance == 0)else

}

思路:

1、滑動視窗由大至小壓縮

2、視窗從起始0位置向後滑動

3、視窗內的字串為有效括號返回

4、剪枝條件:視窗大小為偶數,視窗首尾字元為 '(',')'

public int longestvalidparentheses(string s) 

int maxslide = s.length();

char strs = s.tochararray();

while(maxslide > 1)

for(int i = 0;i <= strs.length - maxslide;i++)

}maxslide--;

} return 0;

}public boolean longestvalidparentheses(char strs,int start,int end)

int balance = 0;

for(int i = start; i < end; i++)elseelse

}} if(balance == 0)else

}

缺點:官方最後三個例子字串口太長,超時限制,本地執行時間為3s左右

1、我們用乙個棧來儲存座標。為了方便計算,在最開始的時候,我們將棧裡面放入乙個-1。

2、當遇到的是 '( '的時候,我們將其座標入棧。

3、當遇到的是 ')' 的時候,先彈出棧頂元素,此時需要分兩種情況。

3.1、此時如果棧空了,其實相當於前面已經正好匹配了,然後再進來了乙個')',此時無需更新最大值max,只需將當期座標入               棧。其作用和上面棧初始化的時候放入乙個 -1 相同。

3.2、如果此時棧非空,說明又多了一對匹配。需要更新 max 的值。

public int longestvalidparentheses(string s) 

int max = 0;

stackstack = new stack();

stack.push(-1);

for(int i = 0; i < s.length(); i++)elseelse

}}

return max;

}

這個問題可以通過動態規劃解決。我們定義乙個 dp 陣列,其中第 i 個元素表示以下標為 i 的字元結尾的最長有效子字串的長度。我們將 dp 陣列全部初始化為 0 。現在,很明顯有效的子字串一定以 ')' 結尾。這進一步可以得出結論:以 '(' 結尾的子字串對應的 dp 陣列位置上的值必定為 0 。所以說我們只需要更新 ')' 在 dp 陣列中對應位置的值。為了求出 dp 陣列,我們每兩個字元檢查一次,如果滿足如下條件:

1、s[i] = ')' 且 s[i−1] = '(' ,也就是字串形如"……()",我們可以推出:

dp[i]=dp[i−2]+2

2、s[i] =')'且 s[i−1] = ')' ,也就是字串形如"……) 

)",我們可以推出:

如果:s[i - dp[i-1] - 1] ='(',可以推導出:

dp[i] =

dp[i - 1]

+ 2 +

dp[ i - dp[i - 1] - 2]

這背後的原因是如果倒數第二個 ')'  即 (s[i−1] = ')' )是乙個有效子字串的一部分(記為 sub_str),對於最後乙個 ')' ,如果它是乙個更長子字串的一部分,那麼它一定有乙個對應的 '(' ,它的位置在倒數第二個 ')'  所在的有效子字串的前面(也就是 sub_str 的前面)。因此,如果子字串 sub_str的前面恰好是 '(',那麼我們就用 2 加上 sub_str 的長度(dp[i-1])去更新dp[i]。

除此以外,我們也會把有效子字串 "(sub_str)" 之前的有效子字串的長度也加上,也就是加上dp[i - dp [i-1] -2]。

具體推導過程參見:《最長有效括號題解》

public int longestvalidparentheses(string s) 

int max = 0;

int dp = new int[s.length()];

for(int i = 0; i < s.length(); i++)

if(i > 0)else

}max = math.max(max,dp[i]);

}} return max;

}

死磕mysql 死磕mysql

資料庫建立語句 create database new 建立乙個名為new 的資料庫 drop database new 刪除名為new的資料庫 資料庫名為小寫,當初教我的那個人對我說在某個系統中大寫會出現異常情況,為了方便移植,統一為小寫 show creata database new 檢視建立...

死磕容器 HashTable

hashtable的實現和hashmap差不多,兩者之間只存在幾點不同。hashtable採用 拉鍊法 實現雜湊表。table 為乙個entry陣列型別,代表了拉鍊的節點。每乙個entry代表乙個key value。private transient entry table count entry鍵...

死磕動態規劃

乙個模型三個特徵 理論講解什麼樣的問題適合用動態規劃來解決呢?換句話說,動態規劃能解決的問題有什麼規律可循呢?實際上,動態規劃作為乙個非常成熟的演算法思想,很多人對此已經做了非常全面的總結。我把這部分理論總結為 乙個模型三個特徵 首先,我們來看,什麼是 乙個模型 它指的是動態規劃適合解決的問題的模型...