Algorithm 查找字符串中最长有效括号序列的长度,单位为O(n)时间
我的朋友在一次采访中遇到了一个问题,他被告知有一个O(n)解决方案。然而,我们谁也想不出来。问题是: 有一个字符串只包含Algorithm 查找字符串中最长有效括号序列的长度,单位为O(n)时间,algorithm,language-agnostic,dynamic-programming,code-complexity,Algorithm,Language Agnostic,Dynamic Programming,Code Complexity,我的朋友在一次采访中遇到了一个问题,他被告知有一个O(n)解决方案。然而,我们谁也想不出来。问题是: 有一个字符串只包含(和),查找最长有效括号子字符串的长度,该子字符串应格式正确 例如“”()())“,最长的有效括号是(),长度为4 我用动态规划法解决了这个问题,但它不是O(n)。有什么想法吗 public int getLongestLen(String s) { if (s == null || s.length() == 0) return 0; int
(
和)
,查找最长有效括号子字符串的长度,该子字符串应格式正确
例如“”()())“
,最长的有效括号是()
,长度为4
我用动态规划法解决了这个问题,但它不是O(n)。有什么想法吗
public int getLongestLen(String s) {
if (s == null || s.length() == 0)
return 0;
int len = s.length(), maxLen = 0;
boolean[][] isValid = new boolean[len][len];
for (int l = 2; l < len; l *= 2)
for (int start = 0; start <= len - l; start++) {
if ((s.charAt(start) == '(' && s.charAt(start + l - 1) == ')') &&
(l == 2 || isValid[start+1][start+l-2])) {
isValid[start][start+l-1] = true;
maxLen = Math.max(maxLen, l);
}
}
return maxLen;
}
public int getLongestLen(字符串s){
如果(s==null | | s.length()==0)
返回0;
int len=s.length(),maxLen=0;
boolean[]isValid=新的boolean[len][len];
对于(int l=2;l 对于(int start=0;start我以前做过这个问题,在压力下很难得到O(n)解,这里是用stack求解的
private int getLongestLenByStack(String s) {
//use last to store the last matched index
int len = s.length(), maxLen = 0, last = -1;
if (len == 0 || len == 1)
return 0;
//use this stack to store the index of '('
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < len; i++) {
if (s.charAt(i) == '(')
stack.push(i);
else {
//if stack is empty, it means that we already found a complete valid combo
//update the last index.
if (stack.isEmpty()) {
last = i;
} else {
stack.pop();
//found a complete valid combo and calculate max length
if (stack.isEmpty())
maxLen = Math.max(maxLen, i - last);
else
//calculate current max length
maxLen = Math.max(maxLen, i - stack.peek());
}
}
}
return maxLen;
}
private int getLongestLenByStack(字符串s){
//使用last存储最后匹配的索引
int len=s.length(),maxLen=0,last=-1;
如果(len==0 | | len==1)
返回0;
//使用此堆栈存储“(”的索引
堆栈=新堆栈();
对于(int i=0;i
您可以分别为每个开括号/闭括号递增/递减一个int变量。将此类有效操作的数量(变量不低于0)记录为当前长度,并记录最长的操作,如最大值
public int getLongestLen(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int stack = 0;
int counter = 0;
int max = 0;
for (Character c: s.toCharArray()) {
if (c == '(') {
stack++;
}
if (c == ')') {
stack--;
}
if (stack >= 0) {
counter++;
}
if (stack < 0) {
counter = 0;
stack = 0;
}
if (counter > max && stack == 0) {
max = counter;
}
}
return max;
}
public int getLongestLen(字符串s){
如果(s==null | | s.length()==0){
返回0;
}
int stack=0;
int计数器=0;
int max=0;
for(字符c:s.toCharArray()){
如果(c=='('){
stack++;
}
如果(c==')'){
堆栈--;
}
如果(堆栈>=0){
计数器++;
}
if(堆栈<0){
计数器=0;
堆栈=0;
}
如果(计数器>最大值和堆栈==0){
最大值=计数器;
}
}
返回最大值;
}
刚刚提出了解决方案,如果有什么问题,请发表评论
count = 0 //stores the number of longest valid paranthesis
empty stack s
arr[]; //contains the string which has the input, something like ())(()(
while(i<sizeof(arr))
{
if(a[i] == '(' )
{
if(top == ')' ) //top of a stack,
{
count = 0;
push a[i] in stack;
}
}
else
{
if(top == '(' )
{
count+=2;
pop from stack;
}
else
{
push a[i] in stack;
}
}
}
count=0//存储最长有效时间的数目
空栈
arr[];//包含包含输入的字符串,类似())()(
而(i算法:
1.添加到堆栈
1.1使用-1初始化,句柄),不使用(
2.当您看到)从堆栈中弹出
2.a如果堆栈大小==0(不匹配),则推送当前索引值
2.b如果堆栈大小>0(匹配),则通过从当前索引中减去顶部值的索引来获得最大长度(完全邪恶!)
我们需要在堆栈中存储以前开始的括号的索引
我们将堆栈的第一个元素作为一个特殊元素推送到“-1”或任何其他不会出现在索引中的数字
现在我们遍历字符串,当我们遇到“(“我们推括号,否则当我们遇到”)”时,我们首先弹出它们并
如果堆栈不是空的,我们通过取结果的最大值(初始化为零)以及当前索引和堆栈顶部索引之间的差来查找到该点的最大有效子字符串的长度
否则,如果堆栈为空,则推送索引
int result=0;
stack<int> s1;
s1.push(-1);
for(int i=0;i<s.size();++i)
{
if(s[i]=='(')
s1.push(i);
else if(s[i]==')')
{
s1.pop();
if(!s1.empty())
result=max(result,i-s1.top());
else
s1.push(i);
}
}
cout<<result<<endl;
int结果=0;
堆栈s1;
s1.推力(-1);
对于(inti=0;i,下面的解具有O(n)时间复杂度和O(1)空间复杂度。
这非常直观。
我们首先从左到右遍历字符串,使用通常用于检查parens有效性的“count”方法,查找parens中最长的有效子字符串。在执行此操作时,如果找到子字符串,我们还会记录其最大长度。
向左。
算法如下:
// Initialize variables
1. count = 0, len = 0, max_len_so_far = 0
// Check for longest valid string of parens while traversing from left to right
2. iterate over input string from left to right:
- len += 1
- if next character is '(',
count += 1
- if next character is ')',
count -= 1
- if (count == 0 and len > max_len_so_far),
max_len_so_far = len
- if (count < 0),
len = 0, count = 0
// Set count and len to zero again, but leave max_len_so_far untouched
3. count = 0, len = 0
// Now do a very similar thing while traversing from right to left
// (Though do observe the switched '(' and ')' in the code below)
4. iterate over input string from right to left:
- len += 1
- if next character is ')',
count += 1
- if next character is '(',
count -= 1
- if (count == 0 and len > max_len_so_far),
max_len_so_far = len
- if (count < 0),
len = 0, count = 0
// max_len_so_far is now our required answer
5. Finally,
return max_len_so_far
假设此字符串的索引为零。
我们先从左向右走。
因此,在索引0处,计数将为1,然后在索引1处为2,在索引2处为3,在索引3处为2,在索引4处为1。在这一步中,max_len甚至不会改变,因为计数不再是0。
然后我们从右向左。
在索引4处,计数为1,然后在索引3处计数为2,然后在索引2处计数为1,然后在索引1处计数为0。
此时,len为4,max_len_so_far=0,因此我们将max_len=4。
然后,在索引0处,计数为1。
此时,我们停止并返回4,这确实是正确的答案。
正确性的证明将作为一个包含性练习留给读者。
注意:此算法也可以非常简单地进行调整,以返回括号本身的最长有效子字符串,而不仅仅是其长度。O(n)可以在不使用堆栈的情况下实现,如果您愿意使用动态方法来查找有效元素,然后通过检查相邻元素来增加其大小。
首先我们找到一个单一的“()”
然后我们尝试找到一个更长的字符串,包括:
可能性是:
- (“()”)我们在其中检查索引之前和之后的索引
- “()”()检查下一个有效单位,以便在搜索中不重复它
接下来,我们更新每个循环中当前检查的开始和结束索引<
// Initialize variables
1. count = 0, len = 0, max_len_so_far = 0
// Check for longest valid string of parens while traversing from left to right
2. iterate over input string from left to right:
- len += 1
- if next character is '(',
count += 1
- if next character is ')',
count -= 1
- if (count == 0 and len > max_len_so_far),
max_len_so_far = len
- if (count < 0),
len = 0, count = 0
// Set count and len to zero again, but leave max_len_so_far untouched
3. count = 0, len = 0
// Now do a very similar thing while traversing from right to left
// (Though do observe the switched '(' and ')' in the code below)
4. iterate over input string from right to left:
- len += 1
- if next character is ')',
count += 1
- if next character is '(',
count -= 1
- if (count == 0 and len > max_len_so_far),
max_len_so_far = len
- if (count < 0),
len = 0, count = 0
// max_len_so_far is now our required answer
5. Finally,
return max_len_so_far
"((())"
public static void main(String[] args) {
String s="))((())";
String finalString="";
for(int i=0;i<s.length();i++){
if (s.charAt(i) == '('&& s.charAt(i+1) == ')') {
String ss= s.substring(i, i+2);
finalString=finalString+ss;
// System.out.println(ss);
}
}
System.out.println(finalString.length());
}
def longest_valid_paranthesis(str):
l = len(str)
dp = [0]*len(str)
for i in range(l):
if str[i] == '(':
dp[i] = 0
elif str[i-1] == '(':
dp[i] = dp[i-2] + 2
elif str[i - dp[i-1] - 1] == '(':
dp[i] = dp[i-1] + 2 + dp[i - (dp[i-1] + 2)]