我正在尝试Javascript中的Codility“嵌套”测试。
测试如下:
A string S consisting of N characters is called properly nested if:
S is empty;
S has the form "(U)" where U is a properly nested string;
S has the form "VW" where V and W are properly nested strings.
For example, string "(()(())())" is properly nested but string "())" isn't.
Write a function:
function solution(S);
that, given a string S consisting of N characters, returns 1 if string S is properly nested and 0 otherwise.
For example, given S = "(()(())())", the function should return 1 and given S = "())", the function should return 0, as explained above.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [0..1,000,000];
string S consists only of the characters "(" and/or ")".
我的解决方法是:
function solution(S) {
const elements = S.split('')
const stack = []
if (elements.length > 1000000) return 0
if (elements[0] == ')') return 0
if (elements[0] == '(') stack.push('(')
for (i=0; i < elements.length; i++){
const currentElement = elements[i]
if (currentElement !== '(' && currentElement !== ')') return 0
if (i>0){
if (stack[stack.length-1] == '(' && currentElement == ')') stack.pop()
else stack.push(currentElement)
}
}
if (stack.length) return 0
else return 1
}
这是正确的,但仅返回75%的性能,我看不到如何进一步提高效率,有人有什么建议吗?
答案 0 :(得分:3)
我认为您这样做太复杂了。拆分不是必需的。此外,问题陈述指出该字符串仅包含(
和)
。因此解决方案可以像这样简单(通过所有测试):
function solution(S) {
let count = 0
for (const c of S) {
if (c == '(')
count++
else if (--count < 0)
return 0
}
return count == 0 ? 1 : 0
}
顺便说一句。您的代码中的该语句是错误的:
if (currentElement == ')' && openCount > 0) openCount = openCount - 1
else openCount = openCount + 1
如果由于)
过多而使计数变为负数,则您将增加计数器。因此,也许这毕竟不是性能问题。对于堆栈的解决方案也是如此:如果堆栈为空,则查找stack [-1],并且该堆栈未定义,因此您可以推入下一个元素(尽管在那里它不会失败,因为您将推入)
,并且永远不会被消耗)。同样更有意义的是将栈顶括号的索引推入堆栈,以便(如果您想)显示括号(
属于)
的括号对。如果您只是将(
压入堆栈,则也可以使用计数器。
答案 1 :(得分:0)
在评论中有建议之后,我尝试使用计数器。
尽管如此,它仍然无法提高效率,在具有较深路径的宽阔树上受到了惩罚。
function solution(S) {
// write your code in JavaScript (Node.js 8.9.4)
const elements = S.split('')
let openCount = 0
if (elements.length > 1000000) return 0
if (elements[0] == ')') return 0
if (elements[0] == '(') openCount = 1
for (i=0; i < elements.length; i++){
const currentElement = elements[i]
if (currentElement !== '(' && currentElement !== ')') return 0
if (i>0){
if (currentElement == ')' && openCount > 0) openCount = openCount - 1
else openCount = openCount + 1
}
}
if (openCount !== 0) return 0
else return 1
}
答案 2 :(得分:0)
您的解决方案中有太多的“ if”。尝试了解马拉卡的答案。或者,在下面检查我的解决方案(99%相同)
function solution(S) {
let stack = 0;
for (let i=0; i<S.length; i++) {
S[i] === '(' ? stack++ : stack--;
if (S[i] === '(') {
stack++
} else {
stack--;
if (stack < 0) return 0;
}
}
return stack === 0 ? 1 : 0;
}
答案 3 :(得分:0)
function solution(S) {
let stack=[];
if(!S){
return 1;
}
for(let i=0;i<S.length;i++){
if(S[i]==='('){
stack.push(S[i]);
}else if(stack.length){
stack.pop();
}else{
return 0;
}
}
return stack.length ? 0: 1;
}