Codility嵌套算法测试性能

时间:2019-12-26 21:05:20

标签: javascript algorithm

我正在尝试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%的性能,我看不到如何进一步提高效率,有人有什么建议吗?

4 个答案:

答案 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;
}
相关问题