一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して6日目です。クリックしてイベントの詳細をご覧ください。
Dachang高周波アルゴリズムインタビュー質問:「ブラケット質問シリーズ」では、ブラケット質問の4つの組み合わせを通じて、有限変数ソリューションを通じて動的計画法の意味を定義する方法を学習します。
1.ブラケットの質問I
括弧の有効な組み合わせは、次のことを意味します。
1)左括弧は、正しいペアの右括弧を見つけることができます
2)右括弧は、正しいペアの左括弧を見つけることができます
有効:(())()()(()())など。
無効:(())(など。
括弧で囲まれた文字列が有効かどうかはどうすればわかりますか?
1.分析
効果的な括弧のペアリングの問題を解決するために必要な変数は1つだけです。左括弧に遭遇する場合、count ++、右括弧に遭遇する場合、count--、countが0未満の場合、左括弧よりも右括弧が多いことを意味します。トラバーサルは終了します。カウント==0、有効であることを示します。それ以外の場合は無効です。
2.実現する
public static boolean valid(String s) {
if (s == null || s.length() == 0) {
return false;
}
char[] str = s.toCharArray();
int count = 0;
for (int i = 0; i < str.length; i++) {
count += str[i] == '(' ? 1 : -1;
if (count < 0) {
return false;
}
}
return count == 0;
}
复制代码
2.ブラケットの質問II
括弧の有効な組み合わせは、次のことを意味します。
1)左括弧は、正しいペアの右括弧を見つけることができます
2)右括弧は、正しいペアの左括弧を見つけることができます
有効:(())()()(()())など。
無効:(())(など。
括弧で囲まれた文字列が無効な場合は、全体として有効にするために少なくとも数文字を返します
1.分析
必要な変数は2つだけです。count(意味は括弧の問題Iと同じです)、count == -1の場合、右の括弧が左の括弧より1つ多いことを意味します。このとき、need ++、countは0に復元され、カウント= 0、トラバーサルの完了後にカウント> 0が見つかった場合、左括弧が右括弧よりも大きいことを意味し、閉じ括弧のカウントを補正する必要があるため、少なくとも+カウントが必要です。追加する必要があります。count==0の場合、少なくとも追加する必要があります。
2.実現する
public static int needParentheses(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int count = 0;
int need = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == '(') {
count++;
} else { // 遇到的是')'
if (count == 0) {
need++;
} else {
count--;
}
}
}
return count + need;
}
复制代码
3.ブラケットの質問III
括弧の有効な組み合わせは、次のことを意味します。
1)左括弧は、正しいペアの右括弧を見つけることができます
2)右括弧は、正しいペアの左括弧を見つけることができます
有効な括弧文字列内のネストレベルの最大数を返します
例:(()())はレベル2を返し、(()(()))はレベル3を返し、()(())はレベル2を返します
1.分析
左括弧count++に遭遇した場合、右括弧count--に遭遇した場合、countの最大値は複数のレイヤーにネストされます
2.実現する
// 校验是否是合法有效括号
public static boolean isValid(char[] str) {
if (str == null || str.length == 0) {
return false;
}
int status = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] != ')' && str[i] != '(') {
return false;
}
if (str[i] == ')' && --status < 0) {
return false;
}
if (str[i] == '(') {
status++;
}
}
return status == 0;
}
public static int deep(String s) {
char[] str = s.toCharArray();
if (!isValid(str)) {
return 0;
}
int count = 0;
int max = 0;
for (int i = 0; i < str.length; i++) {
if (str[i] == '(') {
max = Math.max(max, ++count);
} else {
count--;
}
}
return max;
}
复制代码
4.ブラケットの質問IV
括弧の有効な組み合わせは、次のことを意味します。
1)左括弧は、正しいペアの右括弧を見つけることができます
2)右括弧は、正しいペアの左括弧を見つけることができます
括弧で囲まれた文字列の中で最も長い括弧で囲まれた有効な部分文字列の長さを返します
1.分析
サブストリングは連続している必要があります
何から始める
dp[i]
意味:arr [0 ... i]でiで終わる最長の有効な括弧サブストリングの長さ、サブテキスト:左括弧に遭遇した場合dp[i]
、有効な括弧を終了することは不可能であるため、0になります。dp[i]
定義の意味に違反する左括弧付き
現在の位置iが右括弧の場合、i-1位置のdp値は4です。dp[i-1]
これは、前方に押すと4つの有効な括弧を押すことができることを示し、i-5位置の左括弧の場合、少なくともdp[i]
= 5、i-5の位置が右括弧の場合、dp[i]
= 0、一致する左括弧が左側にある場合でも、それは0でもあります。これはdp[i]
、意味が有効な括弧サブストリングの最長の長さであるためです。一致しdp[i-1]
、最長の括弧が記録されています。有効な部分文字列の長さは、一致する左括弧が前にある場合でもdp[i-1]
、適切な値です。
- i位置は閉じ括弧であり
dp[i-1]
、前のビットが閉じ括弧である場合、dp[i]
= 0 - iの位置は右角かっこです。
dp[i-1]
前のビットが左角かっこである場合、dp[i]は少なくともdp[i-1] + 2です。このとき、1ビット先を見越す必要があります。
2.実現する
public static int maxLength(String s) {
if (s == null || s.length() < 2) {
return 0;
}
char[] str = s.toCharArray();
int[] dp = new int[str.length];
int pre = 0;
int ans = 0;
// dp[0] = 0;
for (int i = 1; i < str.length; i++) {
if (str[i] == ')') {
pre = i - dp[i - 1] - 1; // 与str[i]配对的左括号的位置 pre
if (pre >= 0 && str[pre] == '(') {
dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);
}
}
ans = Math.max(ans, dp[i]);
}
return ans;
}
复制代码