由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - 上一道题吧
相关主题
longest valid Parentheses有O(n)算法么one facebook software problem
nvidia面试题职业杯9.10堆盒子。答案的最后一句为啥返回clone();
A simple interview question也发一个 F,L,G 电面
给定字符串,求其不出现重复字符的子字符串的最大长度题目: iterative binary tree post order traversal
求G加一题的线性解法请教一道面试题,关于tree的
Google onsite 题目求助LeetCode Jump Game [Runtime Error]
发个面试coding题,攒人品问一个关于括号的题目
关于leetcode上的一道题新鲜的T电面题
相关话题的讨论汇总
话题: max话题: len话题: str话题: int话题: curlen
进入JobHunting版参与讨论
1 (共1页)
p*****2
发帖数: 21240
1
一个字符串里边只有 '(' 和 ')'
判断最长的substring, 里边的(和)是合法match的。
输出最长的长度和具有这个长度子串的数目。
比如
(())
4 1
())()
2 2
i******r
发帖数: 793
2
想到一个O(n^2)的做法
应该能有更快的
p*****2
发帖数: 21240
3

目标是O(n)

【在 i******r 的大作中提到】
: 想到一个O(n^2)的做法
: 应该能有更快的

i******r
发帖数: 793
4
嗯,O(n)没错
用一个stack,左括号进栈,右括号看看能否出栈
这样scan一次就行了
i**********e
发帖数: 1145
5
我想到一个办法,利用双链表来表达字符串,每个字符中间有一个数字(首先全都初始
化为 0 )。
然后一次从头到尾扫描,注意以下这两个条件:
- 每次看到数字左边和右边个别是 ‘(’和‘)’就删掉左边和右边的 node,然后把
数字本身 + 2.
- 另外,如果左边也是个数字,就两个数字加起来进行合并。
直到以上两个条件不符合为止,就继续看下一个 node。
这个似乎要花费 O(n) 空间,但应该是 amortized O(n) 时间.
i******r
发帖数: 793
6
这个实现起来麻烦,呵呵

【在 i**********e 的大作中提到】
: 我想到一个办法,利用双链表来表达字符串,每个字符中间有一个数字(首先全都初始
: 化为 0 )。
: 然后一次从头到尾扫描,注意以下这两个条件:
: - 每次看到数字左边和右边个别是 ‘(’和‘)’就删掉左边和右边的 node,然后把
: 数字本身 + 2.
: - 另外,如果左边也是个数字,就两个数字加起来进行合并。
: 直到以上两个条件不符合为止,就继续看下一个 node。
: 这个似乎要花费 O(n) 空间,但应该是 amortized O(n) 时间.

i**********e
发帖数: 1145
7
啊,你说得对,看了你的思路突然想到用 stack 来储存括号和数字就好了,不需要链
表,空间也省一点。

【在 i******r 的大作中提到】
: 嗯,O(n)没错
: 用一个stack,左括号进栈,右括号看看能否出栈
: 这样scan一次就行了

i**********e
发帖数: 1145
8
你是说实现双链表么,呵呵
双链表实现删除和插入的确麻烦。
不过思路方面应该跟你的一样。

【在 i******r 的大作中提到】
: 这个实现起来麻烦,呵呵
H***e
发帖数: 476
9
keep一个左括号的count,括号对数countB
遇到 ( , count++;
遇到 ), count--; 同时 把括号对数 countB++
然后 一旦遇到)并且左括号的为0了,此时说明所有前面的都不再对以后valid了,这时
候countB是一个候选值,跟max 比较,然后countB set to 0; 再继续。。
不知道对否
喔, 还要keep一个变量来记录当前最长长度子串的数目。

【在 p*****2 的大作中提到】
: 一个字符串里边只有 '(' 和 ')'
: 判断最长的substring, 里边的(和)是合法match的。
: 输出最长的长度和具有这个长度子串的数目。
: 比如
: (())
: 4 1
: ())()
: 2 2

p*****2
发帖数: 21240
10
(())
(0(0)0)
第一遍扫描
(020)
(2)
4
()()
(0)0(0)
20(0)
2(0)
22
4
())()
(0)0)0(0)
20)0(0)
2)0(0)
2)02
2)2
应该是work的。
相关主题
Google onsite 题目求助one facebook software problem
发个面试coding题,攒人品职业杯9.10堆盒子。答案的最后一句为啥返回clone();
关于leetcode上的一道题也发一个 F,L,G 电面
进入JobHunting版参与讨论
i**********e
发帖数: 1145
11
不用重复扫描,一次就行。
不过要重复判定那两个条件进行合并,直到不符合为止,才进行看下一个。

【在 p*****2 的大作中提到】
: (())
: (0(0)0)
: 第一遍扫描
: (020)
: (2)
: 4
: ()()
: (0)0(0)
: 20(0)
: 2(0)

p*****2
发帖数: 21240
12

我刚开始用的差不多这个思路不太对。
((((()(((()

【在 H***e 的大作中提到】
: keep一个左括号的count,括号对数countB
: 遇到 ( , count++;
: 遇到 ), count--; 同时 把括号对数 countB++
: 然后 一旦遇到)并且左括号的为0了,此时说明所有前面的都不再对以后valid了,这时
: 候countB是一个候选值,跟max 比较,然后countB set to 0; 再继续。。
: 不知道对否
: 喔, 还要keep一个变量来记录当前最长长度子串的数目。

i**********e
发帖数: 1145
13
peking2,你有想到更好的办法吗?
p*****2
发帖数: 21240
14

我知道。一次扫描就够了。只是需要回溯一下。不过整体还是(N)的时间。我刚才就
是证明你的算法是对的。

【在 i**********e 的大作中提到】
: 不用重复扫描,一次就行。
: 不过要重复判定那两个条件进行合并,直到不符合为止,才进行看下一个。

H***e
发帖数: 476
15
蒽。 错的。 ...

【在 p*****2 的大作中提到】
:
: 我知道。一次扫描就够了。只是需要回溯一下。不过整体还是(N)的时间。我刚才就
: 是证明你的算法是对的。

p*****2
发帖数: 21240
16

可以用stack 和 dp。不过我也是在有提示的情况下做出来的。我本来是hbase的思路。
但是做不对。没想到你那个思路。你这么快能想到正确的解法还是挺赞的。
public class test
{
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
String str=in.next();
int[] dp=new int[str.length()];
Arrays.fill(dp,-1);
Stack stack=new Stack();
int max=0;
int maxcount=0;

for(int i=0;i {
char c=str.charAt(i);
if(c=='(')
{
stack.add(i);
}
else
{
if(!stack.isEmpty())
{
int m=stack.pop();
if(m>0 && dp[m-1]!=-1)
dp[i]=Math.min(dp[m-1],m);
else
dp[i]=m;

int len=i-dp[i]+1;
if(len>max)
{
max=len;
maxcount=1;
}
else if(len==max)
maxcount++;
}
}
}

if(max>0)
System.out.println(max+" "+maxcount);
else
System.out.println("0 1");
}
}

【在 i**********e 的大作中提到】
: peking2,你有想到更好的办法吗?
i******r
发帖数: 793
17
再解释一下我的做法:
1.只有左括号进栈,右括号不进栈
2.栈里面记录括号在字符串的下标,这样就可以计算长度
i******r
发帖数: 793
18
re
和我想的一样

【在 p*****2 的大作中提到】
:
: 可以用stack 和 dp。不过我也是在有提示的情况下做出来的。我本来是hbase的思路。
: 但是做不对。没想到你那个思路。你这么快能想到正确的解法还是挺赞的。
: public class test
: {
: public static void main(String[] args)
: {
: Scanner in=new Scanner(System.in);
: String str=in.next();
: int[] dp=new int[str.length()];

m******6
发帖数: 82
19
stack
O(n)?

【在 p*****2 的大作中提到】
: 一个字符串里边只有 '(' 和 ')'
: 判断最长的substring, 里边的(和)是合法match的。
: 输出最长的长度和具有这个长度子串的数目。
: 比如
: (())
: 4 1
: ())()
: 2 2

i******r
发帖数: 793
20
每个括号最多进栈一次,出栈一次
当然就是O(n)的

【在 m******6 的大作中提到】
: stack
: O(n)?

相关主题
题目: iterative binary tree post order traversal问一个关于括号的题目
请教一道面试题,关于tree的新鲜的T电面题
LeetCode Jump Game [Runtime Error]再问一个算法题。
进入JobHunting版参与讨论
r*****k
发帖数: 1281
21
大侠们帮看看对不对。。。
思想:从第一个开始扫描 遇到 (, i++
遇到 ), 如果i>0 {i--; 如果i==0 或者下一个字符不是),说明找到一个local
longest
match,reset i=0,比较这个是不是目前最大match, 是就存起来,不是就抛弃}
------------------------------------
void matchs(char* str, int& max, int &num){
int i =0; max=0, num=0;
int curr_len=0;

if(*str == '\0' || str == NULL) {max=0; num=0; return;}

//if there is a match, put the len of this match to vector
vector match;
while(*str != '\0'){
char next = *(str+1);
if(*str == '('){
i++;
}
else{
if(i>0) {
i--;
curr_len += 2;
//find a match
if(i==0 || next != ')'){
if(curr_len >= max) {
max = curr_len;
match.push_back(max);
}
curr_len=0;
i=0;
}
}
}
cout<<*str<<" i="< str++;
}
//compute the number of matchs, which have the maximum lenth
vector::iterator it;
for(it = match.begin(); it!= match.end(); it++)
if(*it==max) num++;
}
p*****2
发帖数: 21240
22

你自己run的结果对吗?

【在 r*****k 的大作中提到】
: 大侠们帮看看对不对。。。
: 思想:从第一个开始扫描 遇到 (, i++
: 遇到 ), 如果i>0 {i--; 如果i==0 或者下一个字符不是),说明找到一个local
: longest
: match,reset i=0,比较这个是不是目前最大match, 是就存起来,不是就抛弃}
: ------------------------------------
: void matchs(char* str, int& max, int &num){
: int i =0; max=0, num=0;
: int curr_len=0;
:

r*****k
发帖数: 1281
23
测试了几个小例子 是对的
不知道有没有大bug啊
r*****k
发帖数: 1281
24
太弱了 调试了一个多小时。。

【在 r*****k 的大作中提到】
: 大侠们帮看看对不对。。。
: 思想:从第一个开始扫描 遇到 (, i++
: 遇到 ), 如果i>0 {i--; 如果i==0 或者下一个字符不是),说明找到一个local
: longest
: match,reset i=0,比较这个是不是目前最大match, 是就存起来,不是就抛弃}
: ------------------------------------
: void matchs(char* str, int& max, int &num){
: int i =0; max=0, num=0;
: int curr_len=0;
:

m******6
发帖数: 82
25
input: (()))
output: 22
expected:41

【在 p*****2 的大作中提到】
:
: 你自己run的结果对吗?

m******6
发帖数: 82
26
input (()))
output:22
expected:41

【在 p*****2 的大作中提到】
:
: 你自己run的结果对吗?

p*****2
发帖数: 21240
27

are you sure?

【在 m******6 的大作中提到】
: input: (()))
: output: 22
: expected:41

m******6
发帖数: 82
28
yes, did you test?
let me check if there is typo in my version.

【在 p*****2 的大作中提到】
:
: are you sure?

p*****2
发帖数: 21240
29

dp[i]=Math.min(dp[m-1],m);
这句可以处理这种情况呀。我的已经pass了。

【在 m******6 的大作中提到】
: yes, did you test?
: let me check if there is typo in my version.

c*****n
发帖数: 96
30
像peking2说的, 这个算法对(((()(((()不成立。 我想可以再反向扫描一遍, 这次用
一个变量记录右括号的数目, 对( , count--, 对 ), count++
两次扫描后, 取其大值。

【在 H***e 的大作中提到】
: keep一个左括号的count,括号对数countB
: 遇到 ( , count++;
: 遇到 ), count--; 同时 把括号对数 countB++
: 然后 一旦遇到)并且左括号的为0了,此时说明所有前面的都不再对以后valid了,这时
: 候countB是一个候选值,跟max 比较,然后countB set to 0; 再继续。。
: 不知道对否
: 喔, 还要keep一个变量来记录当前最长长度子串的数目。

相关主题
贡献一道G家的面试题nvidia面试题
一道题:number of permutation是 for a total scoreA simple interview question
longest valid Parentheses有O(n)算法么给定字符串,求其不出现重复字符的子字符串的最大长度
进入JobHunting版参与讨论
L***Q
发帖数: 508
31
大学时候学编译原理,里面讲的括号匹配就是用stack来做滴。

【在 i**********e 的大作中提到】
: 啊,你说得对,看了你的思路突然想到用 stack 来储存括号和数字就好了,不需要链
: 表,空间也省一点。

r*****k
发帖数: 1281
32
你还记得阿。我都忘了。

★ 发自iPhone App: ChineseWeb - 中文网站浏览器

【在 L***Q 的大作中提到】
: 大学时候学编译原理,里面讲的括号匹配就是用stack来做滴。
L***Q
发帖数: 508
33
当年俺们的course project是写一个简单的compiler,把简单的C语言编译成可执行的
程序。俺用VB写的,嘿嘿,饱受鄙视

【在 r*****k 的大作中提到】
: 你还记得阿。我都忘了。
:
: ★ 发自iPhone App: ChineseWeb - 中文网站浏览器

r*****k
发帖数: 1281
34
唉,不错了。我都是抄你这样的牛人的。。

【在 L***Q 的大作中提到】
: 当年俺们的course project是写一个简单的compiler,把简单的C语言编译成可执行的
: 程序。俺用VB写的,嘿嘿,饱受鄙视

i**********e
发帖数: 1145
35
反例:
"()()", max = 4,但你的结果是 max = 2.

【在 r*****k 的大作中提到】
: 大侠们帮看看对不对。。。
: 思想:从第一个开始扫描 遇到 (, i++
: 遇到 ), 如果i>0 {i--; 如果i==0 或者下一个字符不是),说明找到一个local
: longest
: match,reset i=0,比较这个是不是目前最大match, 是就存起来,不是就抛弃}
: ------------------------------------
: void matchs(char* str, int& max, int &num){
: int i =0; max=0, num=0;
: int curr_len=0;
:

r*****k
发帖数: 1281
36
看怎么定义一个合法的match吧。
我的理解是(())算一个合法match。()()实际上是2个合法match,每个长度为
二。

★ 发自iPhone App: ChineseWeb - 中文网站浏览器

【在 i**********e 的大作中提到】
: 反例:
: "()()", max = 4,但你的结果是 max = 2.

p*****2
发帖数: 21240
37

题目的要求是连续最大的。()()是连续的,算一个。

【在 r*****k 的大作中提到】
: 看怎么定义一个合法的match吧。
: 我的理解是(())算一个合法match。()()实际上是2个合法match,每个长度为
: 二。
:
: ★ 发自iPhone App: ChineseWeb - 中文网站浏览器

H***e
发帖数: 476
38
这样行不行会不会简单点:
用一个boolean[] flags 来indicate对应的括号是不是最后valid,valid就是可以组成
一对被stack pop出去
用stack来进出一遍决定此 flags (入stack的也包括括号的index,这样好写flags)
然后扫描一遍flags这个array,看连续为1的最长的连续子array, 及其个数。
r*****k
发帖数: 1281
39
那我的就不对了。
不过我觉得()()算一个不怎么make sense, 因为它其实包括了两个独立的单元。而(())
算一个很好理解,他就是一个整体。

★ 发自iPhone App: ChineseWeb - 中文网站浏览器

【在 p*****2 的大作中提到】
:
: 题目的要求是连续最大的。()()是连续的,算一个。

H***e
发帖数: 476
40
原体意思是最长的string可以组成合法的括号结构
((((((())))))) 这个算一
()()()()()这个一算一

))

【在 r*****k 的大作中提到】
: 那我的就不对了。
: 不过我觉得()()算一个不怎么make sense, 因为它其实包括了两个独立的单元。而(())
: 算一个很好理解,他就是一个整体。
:
: ★ 发自iPhone App: ChineseWeb - 中文网站浏览器

相关主题
给定字符串,求其不出现重复字符的子字符串的最大长度发个面试coding题,攒人品
求G加一题的线性解法关于leetcode上的一道题
Google onsite 题目求助one facebook software problem
进入JobHunting版参与讨论
r*****k
发帖数: 1281
41
把我程序里面的match found condition
从if(i==0 || next != ')') 改为 if(i==0 && next != '(')应该就可以handle你这种
情况了。
-----------------------------------------------------
void matchs1(char* str, int& max, int &num){
int i =0; max=0, num=0;
int curr_len=0;

if(*str == '\0' || str == NULL) {max=0; num=0; return;}

//if there is a match, put the len of this match to vector
vector match;
while(*str != '\0'){
char next = *(str+1);
if(*str == '('){
i++;
}
else{
if(i>0) {
i--;
curr_len += 2;
//find a match
if(i==0 && next != '(')

{
if(curr_len >= max) {
max = curr_len;
match.push_back(max);
}
cout<<"max="< curr_len=0;
i=0;
}
}
}
cout<<*str<<" i="< str++;
}
//compute the number of matchs, which have the maximum lenth
vector::iterator it;
for(it = match.begin(); it!= match.end(); it++)
if(*it==max) num++;
}

【在 H***e 的大作中提到】
: 原体意思是最长的string可以组成合法的括号结构
: ((((((())))))) 这个算一
: ()()()()()这个一算一
:
: ))

i**********e
发帖数: 1145
42
try "(()", max = 2

【在 r*****k 的大作中提到】
: 把我程序里面的match found condition
: 从if(i==0 || next != ')') 改为 if(i==0 && next != '(')应该就可以handle你这种
: 情况了。
: -----------------------------------------------------
: void matchs1(char* str, int& max, int &num){
: int i =0; max=0, num=0;
: int curr_len=0;
:
: if(*str == '\0' || str == NULL) {max=0; num=0; return;}
:

r*****k
发帖数: 1281
43
嗯,很多bug。。
还要加强修炼。。

★ 发自iPhone App: ChineseWeb - 中文网站浏览器

【在 i**********e 的大作中提到】
: try "(()", max = 2
i**********e
发帖数: 1145
44
应该不是bug的问题,而是你这个思路方向不对,无法处理所有case。
问题在于:
当你看到 ")" 的时候,你无法找到之前的 "(" 来区配。
你必须用一个 stack 来储存之前遇到的所有 "("

【在 r*****k 的大作中提到】
: 嗯,很多bug。。
: 还要加强修炼。。
:
: ★ 发自iPhone App: ChineseWeb - 中文网站浏览器

r*****k
发帖数: 1281
45
i其实就相当于一个stack。

★ 发自iPhone App: ChineseWeb - 中文网站浏览器

【在 i**********e 的大作中提到】
: 应该不是bug的问题,而是你这个思路方向不对,无法处理所有case。
: 问题在于:
: 当你看到 ")" 的时候,你无法找到之前的 "(" 来区配。
: 你必须用一个 stack 来储存之前遇到的所有 "("

p*i
发帖数: 411
46
#include
#include
#include
using namespace std;
void process(const string& str) {
stack s, s1;
for (unsigned i = 0; i < str.size(); i++) {
if ('(' == str[i]) {
s.push(i);
} else {
if (!s.empty()) {
unsigned left = s.top(); s.pop();
unsigned& right = i;
if (s1.empty() || (s1.top()+1 < left)) {
s1.push(left);
s1.push(right);
} else if (s1.top()+1 == left) {
s1.pop();
s1.push(right);
} else {
s1.pop(); s1.pop();
s1.push(left);
s1.push(right);
}
}
}
}
unsigned max_len = 0, max_cnt = 1;
while (!s1.empty()) {
unsigned left, right;
right = s1.top(); s1.pop();
left = s1.top(); s1.pop();
unsigned len = right-left+1;
if (len > max_len) {
max_len = len; max_cnt = 1;
} else if (len == max_len) {
max_cnt++;
}
}
cout << max_len << "\t" << max_cnt << endl;
}
int main(int argc, char** argv) {
if (argc < 2) {
cout << "Usage: " << argv[0] << " str" << endl;
return 0;
}
process(argv[1]);
return 0;
}

【在 p*****2 的大作中提到】
: 一个字符串里边只有 '(' 和 ')'
: 判断最长的substring, 里边的(和)是合法match的。
: 输出最长的长度和具有这个长度子串的数目。
: 比如
: (())
: 4 1
: ())()
: 2 2

c*****n
发帖数: 96
47
int getLongestBrackets(char *str, int *num){
char *p = str;
int diff = 0;
int maxLen = 0;
int curLen = 0;

while (*p){
while (*p && *p == ')') p++;
while (*p && diff >= 0){
if (*p == '(') diff ++;
if (*p == ')') diff --;
curLen++;
}
if (*p || diff <= 0){
curLen += diff;
if (curLen > maxLen){
maxLen = curLen;
*num = 0;
} else if(curLen == maxLen){
*num += 1;
}
}
curLen = 0;
}

p--;
curLen = 0;
diff = 0;
while (p>= str){
while (p >= str && *p == '(') p--;
while (p >= str && diff >= 0){
if (*p == ')') diff ++;
if (*p == '(') diff --;
curLen ++;
}
if (p >= str || diff <= 0){
curLen += diff;
if (curLen > maxLen){
maxLen = curLen;
*num = 0;
} else if(curLen == maxLen){
*num += 1;
}
}
curLen = 0;
}

return maxLen;
}
h********e
发帖数: 1972
48
O(n)算法:
扫一遍数组遇到( +1, ) -1. 把数记录在数组里。如果遇到负数就停。(后面剩下的括弧可以当做一个新问题重新处理, 显然遇到负数,那么这个 ')'无法作为合法串的一部分。 )
把记下来的数作为key,位置作为value,散列到[0,i]的桶里面。(假设在i位置遇到负数)在每个桶里面求最大距离。 然后再在各个桶之间求最大距离。
然后处理剩下的括弧。repeat
h********e
发帖数: 1972
49
O(n)算法2:
stack s; //contains, '(', numbers
int c = 0;
int max = 0;
for (i = 0 to n-1)
{
if A(i) == '(', {s.push('('); c++; }
if A(i) == ')' {
if (c == 0) break (restart the process from the next '(');
else if (s.top == '(') {
s.pop();
if (s.top is a number)) s.top += 2;
else s.push(2);
if (max < s.top) max = s.top;
}
else if (s.top is a number) // s = [... X '('N ] case
{
_n = s.pop();
s.pop(); //pop out '('
if (s.top is a number) s.top+= _n; else s.push(_n);
update max...
}
c--;
}
}
}
So finally, s will be like ((N(N(N(( where N are the numbers.
i**********e
发帖数: 1145
50
你这算法会导致 O(n^2) 不是吗?
> 然后处理剩下的括弧。repeat

的括弧可以当做一个新问题重新处理, 显然遇到负数,那么这个 ')'无法作为合法串的
一部分。 )
负数)在每个桶里面求最大距离。 然后再在各个桶之间求最大距离。

【在 h********e 的大作中提到】
: O(n)算法:
: 扫一遍数组遇到( +1, ) -1. 把数记录在数组里。如果遇到负数就停。(后面剩下的括弧可以当做一个新问题重新处理, 显然遇到负数,那么这个 ')'无法作为合法串的一部分。 )
: 把记下来的数作为key,位置作为value,散列到[0,i]的桶里面。(假设在i位置遇到负数)在每个桶里面求最大距离。 然后再在各个桶之间求最大距离。
: 然后处理剩下的括弧。repeat

相关主题
职业杯9.10堆盒子。答案的最后一句为啥返回clone();请教一道面试题,关于tree的
也发一个 F,L,G 电面LeetCode Jump Game [Runtime Error]
题目: iterative binary tree post order traversal问一个关于括号的题目
进入JobHunting版参与讨论
h********e
发帖数: 1972
51
不会哈。 每次做到负数 就把前面的扔了吧。剩下的括弧的意思就是出现负数以后后面的。。这个算法跟栈那个其实一样的
i**********e
发帖数: 1145
52
"()(())" 返回的是 4,不是6.

【在 p*i 的大作中提到】
: #include
: #include
: #include
: using namespace std;
: void process(const string& str) {
: stack s, s1;
: for (unsigned i = 0; i < str.size(); i++) {
: if ('(' == str[i]) {
: s.push(i);
: } else {

i**********e
发帖数: 1145
53
不是很明白,给个例子:
"(()()(())(("
标记为:
1 2 1 2 1 2 3 2 1 2 3
key->value:
1 -> 0,2,4,8
2 -> 1,3,5,7,9
3 -> 6,10
这里 在桶 1 的最大距离是 [0,8] = 8.
但是 在桶 2 的最大距离 [1,9] = 8 是不合法的。
当然,你可以很容易判定桶里面的两个 index 是否合法。但是这样不能要一个一个在
桶里取两个值来判定吧。
这里感觉漏掉了些逻辑,不知道我有没有理解正确。谢谢。

的括弧可以当做一个新问题重新处理, 显然遇到负数,那么这个 ')'无法作为合法串的
一部分。 )
负数)在每个桶里面求最大距离。 然后再在各个桶之间求最大距离。

【在 h********e 的大作中提到】
: O(n)算法:
: 扫一遍数组遇到( +1, ) -1. 把数记录在数组里。如果遇到负数就停。(后面剩下的括弧可以当做一个新问题重新处理, 显然遇到负数,那么这个 ')'无法作为合法串的一部分。 )
: 把记下来的数作为key,位置作为value,散列到[0,i]的桶里面。(假设在i位置遇到负数)在每个桶里面求最大距离。 然后再在各个桶之间求最大距离。
: 然后处理剩下的括弧。repeat

c*****n
发帖数: 96
54
ihasleetcode, 能否看看我的算法是否有问题? 谢谢。

【在 i**********e 的大作中提到】
: 不是很明白,给个例子:
: "(()()(())(("
: 标记为:
: 1 2 1 2 1 2 3 2 1 2 3
: key->value:
: 1 -> 0,2,4,8
: 2 -> 1,3,5,7,9
: 3 -> 6,10
: 这里 在桶 1 的最大距离是 [0,8] = 8.
: 但是 在桶 2 的最大距离 [1,9] = 8 是不合法的。

i**********e
发帖数: 1145
55
我制造了一些测试数据,你的程序显示 Time Limit Exceeded.
不知道是哪个test 造成的,我再测试一下哈。

【在 c*****n 的大作中提到】
: ihasleetcode, 能否看看我的算法是否有问题? 谢谢。
H***e
发帖数: 476
56
大牛帮看下有明线错误吗?
》》》
发信人: Hbase (每天都进步一点点), 信区: JobHunting
标 题: Re: 上一道题吧
发信站: BBS 未名空间站 (Wed Feb 29 19:21:56 2012, 美东)
这样行不行会不会简单点:
用一个boolean[] flags 来indicate对应的括号是不是最后valid,valid就是可以组成
一对被stack pop出去
用stack来进出一遍决定此 flags (入stack的也包括括号的index,这样好写flags)
然后扫描一遍flags这个array,看连续为1的最长的连续子array, 及其个数

【在 i**********e 的大作中提到】
: 我制造了一些测试数据,你的程序显示 Time Limit Exceeded.
: 不知道是哪个test 造成的,我再测试一下哈。

i**********e
发帖数: 1145
57
你测试过你程序吗?
"(" 这个 test case 就过不了,似乎有死循环。

【在 c*****n 的大作中提到】
: ihasleetcode, 能否看看我的算法是否有问题? 谢谢。
c*****n
发帖数: 96
58
发现一个bug: 第2遍扫描前没有reset 变量 diff. 这可能造成死循环。我更新了code
, 麻烦你再试一下。谢谢。

【在 i**********e 的大作中提到】
: 我制造了一些测试数据,你的程序显示 Time Limit Exceeded.
: 不知道是哪个test 造成的,我再测试一下哈。

i**********e
发帖数: 1145
59
你这思路基本跟 peking2 和 itworker 的一样,只不过你的需要扫两遍.
直接利用数组储存 开括号 "(" 的下标 (或者直接储存在 stack 里)就可以了,然后
看到 ")" 的时候,可以从stack里得到对应的 "(" 的下标,直接就能得到距离了啦,
这样扫描一遍就能得到最大距离。
EDIT:
不好意思,看来逻辑还是有点漏洞,以上的算法不能处理这种情况 "()(())",这样的话应该就必须像 peking2 用数组来保存之前的结果,然后看开括号之前的一个结果,加上去。

【在 H***e 的大作中提到】
: 大牛帮看下有明线错误吗?
: 》》》
: 发信人: Hbase (每天都进步一点点), 信区: JobHunting
: 标 题: Re: 上一道题吧
: 发信站: BBS 未名空间站 (Wed Feb 29 19:21:56 2012, 美东)
: 这样行不行会不会简单点:
: 用一个boolean[] flags 来indicate对应的括号是不是最后valid,valid就是可以组成
: 一对被stack pop出去
: 用stack来进出一遍决定此 flags (入stack的也包括括号的index,这样好写flags)
: 然后扫描一遍flags这个array,看连续为1的最长的连续子array, 及其个数

i**********e
发帖数: 1145
60
试了,还是死循环啊。

code

【在 c*****n 的大作中提到】
: 发现一个bug: 第2遍扫描前没有reset 变量 diff. 这可能造成死循环。我更新了code
: , 麻烦你再试一下。谢谢。

相关主题
新鲜的T电面题一道题:number of permutation是 for a total score
再问一个算法题。longest valid Parentheses有O(n)算法么
贡献一道G家的面试题nvidia面试题
进入JobHunting版参与讨论
h********e
发帖数: 1972
61
多谢。。跟我想象中的有点不一样。。找最大距离的时候要从一个(开始,以)结束,
这个match也很简单,找最远的就行。我的算法描述里面貌似漏了这点。。不过那个算
法最后应该会end up with the same as stack..

【在 i**********e 的大作中提到】
: 不是很明白,给个例子:
: "(()()(())(("
: 标记为:
: 1 2 1 2 1 2 3 2 1 2 3
: key->value:
: 1 -> 0,2,4,8
: 2 -> 1,3,5,7,9
: 3 -> 6,10
: 这里 在桶 1 的最大距离是 [0,8] = 8.
: 但是 在桶 2 的最大距离 [1,9] = 8 是不合法的。

H***e
发帖数: 476
62

谢谢!

的话应该就必须像 peking2 用数组来保存之前的结果,然后看开括号之前的一个结果
,加上去。

【在 i**********e 的大作中提到】
: 你这思路基本跟 peking2 和 itworker 的一样,只不过你的需要扫两遍.
: 直接利用数组储存 开括号 "(" 的下标 (或者直接储存在 stack 里)就可以了,然后
: 看到 ")" 的时候,可以从stack里得到对应的 "(" 的下标,直接就能得到距离了啦,
: 这样扫描一遍就能得到最大距离。
: EDIT:
: 不好意思,看来逻辑还是有点漏洞,以上的算法不能处理这种情况 "()(())",这样的话应该就必须像 peking2 用数组来保存之前的结果,然后看开括号之前的一个结果,加上去。

p*****2
发帖数: 21240
63

不好意思,没时间帮你看你的答案。这题想作对可不容易。我按照以前的想法怎么做都
有漏洞,补了这个就出那个。你要想判断最好去oj一下。

【在 H***e 的大作中提到】
: 蒽
: 谢谢!
:
: 的话应该就必须像 peking2 用数组来保存之前的结果,然后看开括号之前的一个结果
: ,加上去。

i**********e
发帖数: 1145
64
我总结一下吧,其实这题标准解法就应该像 peking2 的解法一样.
itworker 的解法 只是利用 stack 记住开括号的下标,这是不够的,因为无法处理这
种情况:"()()(())".每次看到关括号,只能知道区配的开括号的位置,但这不一定是
最长距离。
用数组保存之前的结果,就是因为要处理以上这样的情况。 stack 只能告诉你区配关
括号的起始位置。
我的解法用双链表也可以,思路虽然容易解释明白,但是编起来的确麻烦不少,不好写。
这题 O(n^3) 暴力解很容易想到, O(n^2) 优化也可以很直接,但是 O(n) 的解法还不
是很明显,利用了stack的特性还有基本 dp 的道理,的确很巧妙。
c*****n
发帖数: 96
65
一次性写出bug free的code太难了:(. 刚才没有编译器,就直接在网上写的code, 才
发现忘记修改循环变量的值了。 还要多练啊。

【在 i**********e 的大作中提到】
: 试了,还是死循环啊。
:
: code

i**********e
发帖数: 1145
66
对,重点在于怎么都不能处理general case,无数次的往前回溯这个道理。

【在 p*****2 的大作中提到】
:
: 不好意思,没时间帮你看你的答案。这题想作对可不容易。我按照以前的想法怎么做都
: 有漏洞,补了这个就出那个。你要想判断最好去oj一下。

i**********e
发帖数: 1145
67
真的很难。
我昨晚利用想到的双链表那个思路写代码,思路很清晰,而且双链表都有自己写好的现
成class,照理说问题不大。
结果写着写着才发现非常不好写,漏掉了一些判定条件。
所以还是要多写多练习。

【在 c*****n 的大作中提到】
: 一次性写出bug free的code太难了:(. 刚才没有编译器,就直接在网上写的code, 才
: 发现忘记修改循环变量的值了。 还要多练啊。

h********e
发帖数: 1972
68
这题我觉得如果意识到遇到负数的时候可以吧前面的都扔了。基本上stack的做法就已经出来一半了。我把bucket的方法想完的时候,stack的做法很自然就弄出来了。
i**********e
发帖数: 1145
69
恩,是的。
遇到负数的时候就代表 stack 已经清空了,没有开括号来区配了。

已经出来一半了。我把bucket的方法想完的时候,stack的做法很自然就弄出来了。

【在 h********e 的大作中提到】
: 这题我觉得如果意识到遇到负数的时候可以吧前面的都扔了。基本上stack的做法就已经出来一半了。我把bucket的方法想完的时候,stack的做法很自然就弄出来了。
i**********e
发帖数: 1145
70
测试数据已经 放在 Online Judge 了。题目为 "Longest Valid Parentheses",方便
大家测试程序。
http://www.leetcode.com/onlinejudge
大家练练手吧。
相关主题
nvidia面试题求G加一题的线性解法
A simple interview questionGoogle onsite 题目求助
给定字符串,求其不出现重复字符的子字符串的最大长度发个面试coding题,攒人品
进入JobHunting版参与讨论
p*i
发帖数: 411
71
感谢帮忙测试。我的已经通过了
基本思想是用一个stack s0,遇到'('就push当前的index,遇到')'就pop,说明发现一
个'('-')' pair
此时left和right分别记录这个pair的左边'('的位置和右边')'的位置
同时还有一个额外的s1,记录当前已经遇到的所有pair的左右位置
每次发现一个新的pair (lnew, rnew),就与s1栈顶的pair(假设是lold, rold)进行比较
如果lnew == rold+1,说明他们是()()这种情况,所以需要合并
如果lnew < rold+1,说明是(())这种情况,也需要合并
一旦进行了第一个合并,就需要继续检查s1直到桟为空或者不能继续合并为止,应付()
(())这种情况
下面是我在leetcode上用的code
#include
using namespace std;
class Solution {
public:
int longestValidParentheses(string s) {
Start typing your C/C++ solution below
// DO NOT write int main() function
stack s0, s1;
for (unsigned i = 0; i < s.size(); i++) {
if ('(' == s[i]) {
s0.push(i);
} else {
if (!s0.empty()) {
unsigned left = s0.top(); s0.pop();
unsigned right = i;
while (!s1.empty()) {
if (s1.empty() || (s1.top()+1 < left)) {
// nothing to merge
break;
} else if (s1.top()+1 == left) {
s1.pop();
left = s1.top(); s1.pop();
} else if (s1.top()+1 > left) {
s1.pop(); s1.pop();
}
}
s1.push(left);
s1.push(right);
}
}
}
unsigned max_len = 0, max_cnt = 1;
while (!s1.empty()) {
unsigned left, right;
right = s1.top(); s1.pop();
left = s1.top(); s1.pop();
unsigned len = right-left+1;
if (len > max_len) {
max_len = len; max_cnt = 1;
} else if (len == max_len) {
max_cnt++;
}
}
return max_len;
}
};

【在 i**********e 的大作中提到】
: 测试数据已经 放在 Online Judge 了。题目为 "Longest Valid Parentheses",方便
: 大家测试程序。
: http://www.leetcode.com/onlinejudge
: 大家练练手吧。

1 (共1页)
进入JobHunting版参与讨论
相关主题
新鲜的T电面题求G加一题的线性解法
再问一个算法题。Google onsite 题目求助
贡献一道G家的面试题发个面试coding题,攒人品
一道题:number of permutation是 for a total score关于leetcode上的一道题
longest valid Parentheses有O(n)算法么one facebook software problem
nvidia面试题职业杯9.10堆盒子。答案的最后一句为啥返回clone();
A simple interview question也发一个 F,L,G 电面
给定字符串,求其不出现重复字符的子字符串的最大长度题目: iterative binary tree post order traversal
相关话题的讨论汇总
话题: max话题: len话题: str话题: int话题: curlen