算法:优化'平衡括号'

时间:2016-01-19 04:56:11

标签: javascript algorithm

我提出了以下问题......

在字符串“({[}])”中给出N个不同的打开和关闭括号,检查字符串是否具有匹配的大括号。如果大括号匹配则返回true,否则返回false。

以下是我提出的答案......

function braceeql(braces){
  var leftpar = 0; 
  var rightpar = 0; 
  var leftbrace = 0;
  var rightbrace = 0;
  var leftcurl = 0;
  var rightcurl = 0;

  for(var index = 0; index < braces.length; index++){
    if(braces[index] == ')'){
      leftpar += 1;
    }else if(braces[index] == '('){
      rightpar += 1;
    }else if(braces[index] == '['){
      leftbrace += 1;
    }else if(braces[index] == ']'){
      rightbrace += 1;
    }else if(braces[index] == '{'){
      leftcurl += 1;
    }else if(braces[index] == '}'){
      rightcurl += 1;
    }
  }
  if(leftcurl == rightcurl && leftbrace == rightbrace && leftpar == rightpar){
    console.log(true)
  }else{
    console.log(false)
  }
}

这是一段非常多的代码,但确实如此。关于其他人如何攻击这个问题,我看到了不同的意见,但我想知道 是否有更好/更清晰的方法来解决这个算法而不会损害大O?

我对建议和其他看待这个问题的方法持开放态度。

8 个答案:

答案 0 :(得分:4)

使用堆栈

以下解决方案的时间复杂度为 O(n)

function isBalanced(str) {
    const map = {
        '(': ')',
        '[': ']',
        '{': '}',
    };
    const closing = Object.values(map);
    const stack = [];

    for (let char of str) {
        if (map[char]) {
            stack.push(char);
        } else if (closing.includes(char) && char !== map[stack.pop()]) {
            return false;
        }
    }
    return !stack.length;
}

答案 1 :(得分:3)

嗯,首先,你的解决方案似乎没有涵盖像()[或({)}这样的情况(我不确定你是否被要求这样做,但是这个玩具问题,因为我知道它要求它)

这是我一年前制作的这个玩具问题的解决方案,但似乎更快(如果它不匹配会更早停止,有更少的ifs和elses)并重复更少的代码,但我不确定从新手的角度来看,更清洁,更容易理解

var braceeql = function(braces){
  var stack = {};
  var size = 0;
  var beginners = ['(', '[', '{'];
  var enders = [')', ']', '}'];
  for(var i = 0; i < braces.length; i++){
    if( beginners.indexOf(braces[i]) !== -1 ){
      stack[size] = braces[i];
      size++;
    } else if( enders.indexOf(braces[i]) !== -1 ){
      if(size === 0) { return false; }
      var index = enders.indexOf(braces[i]);
      if(stack[size-1] === beginners[index] ){
        size --;
      } else {
        return false;
      }
    }
  }

  return size === 0;
};

答案 2 :(得分:0)

这是我对这个问题的看法:

const isBalance = str => {
  const result = !str.split('').reduce((accum, current) => {
    if (accum < 0) return accum
    else {
      if (current === '(') return accum+= 1
      if (current === ')') return accum-= 1
      if (current === '[') return accum+= 2
      if (current === ']') return accum-= 2
      if (current === '{') return accum+= 3
      if (current === '}') return accum-= 3    
    }

  }, 0)

  return result
}

此解决方案将为您提供O(n)。 可以改进此解决方案的一件事是,如果我们达到accum < 0(意味着有一个不匹配的闭括号),立即停止迭代。

另外,阅读代码更容易

答案 3 :(得分:0)

这可能有点麻烦,但是为什么不使用定义良好的堆栈呢?这是一个好习惯。

//stack
class STACK 
{
  //initialize
  constructor()
  {
    this.arr = [];
  }
  //add to stack
  add(data)
  {
    this.arr.push(data);
  }
  //remote from stack
  remove()
  {
    return this.arr.pop();
  }
  //print the stack
  print()
  {
    console.log('-----');
    for(let i = this.arr.length-1; i >=0; i--)
      console.log('|',this.arr[i],'|');
    console.log('-----');
  }
  //peek last element
  peek()
  {
    return this.arr[this.arr.length-1];
  }
  //check if empty
  empty()
  {
    if(this.arr.length===0)
      return true;
    else
      return false;
  }
}

//Use stack to check for balanced paranthesis
const balanceParantheses = (str)=>{
  obj = new STACK();
  for(let char of str)
  {
    if(char==='[' || char==='{' || char ==='(')
      obj.add(char);
    else {
      switch(char)
      {
        case(']'):
          if(obj.empty())
            return false;
          else if(obj.peek()!=='[') {
            return false
          } else obj.remove();
          break;
        case(')'):
          if(obj.empty())
            return false;
          else if(obj.peek()!=='(') {
            return false
          } else obj.remove();
          break;
        case('}'):
          if(obj.empty())
            return false;
          else if(obj.peek()!=='{') {
            return false
          } else obj.remove();
          break;
      }
    }
  }
  return true;
}

console.log(balanceParantheses("[()]{}{[()()]()}"));

答案 4 :(得分:0)

使用计数器变量(来源:解决方案#3,第496页,Fundamentals of Computer Programming with C#):

let openers = {
    curly: '{',
    square: '[',
    paren: '('
  };

  let closers = {
    curly: '}',
    square: ']',
    paren: ')'
  };

  function isBalanced(str) {
    let counter = 0;

    for (let char of str) {
      if (char === openers.curly || char === openers.square || char === openers.paren)
        counter++;

      if (char === closers.curly || char === closers.square || char === closers.paren)
        counter--;

      if (counter < 0) 
        return false;
    }

    return true;
  }
  
  console.log(isBalanced("[]"));
  console.log(isBalanced("]][[[][][][]]["));
  console.log(isBalanced("[][[[[][][[[]]]]]]"));
  console.log(isBalanced("]["));
  console.log(isBalanced("[[[]]]][[]"));
  console.log(isBalanced("[]][[]]][[[[][]]"));
  console.log(isBalanced("[[]][[][]]"));
  console.log(isBalanced("[[]]"));
  console.log(isBalanced("]][]][[]][[["));
  console.log(isBalanced("][]][][["));
  console.log(isBalanced("][]["));
  console.log(isBalanced("[[]]][][][[]]["));
  console.log(isBalanced(""));

答案 5 :(得分:0)

这是我通过Stack结构的解决方案。

const input = '{a[b{c(d)e}f]g}';

function isBalanced(str) {
  let stack = [];
  let closeMap = new Map([
    [']', '['], 
    ['}', '{'], 
    [')', '(']
  ]);
  let openSet = new Set(closeMap.values());

  for (let ch of str) {
    if(closeMap.has(ch) && 
      (!stack.length || stack.pop() != closeMap.get(ch)))
        return false;            
    else if(openSet.has(ch)) 
      stack.push(ch);
    else continue;
  }

  return (!stack.length)
};

console.log('result is: ' + isBalanced(input));

答案 6 :(得分:0)

function isBalanced(str = "") {
    if (typeof str !== "string" || str.trim().length === 0) {
        return false;
    }
    str = str.replace(/[^{}()\[\]]/g, "");
    if (typeof str !== "string" || str.trim().length === 0) {
        return false;
    }
    while (str.length > 0) {
        let perviousLenght = str.length;
        str = str.replace(/\(\)/g, "");
        str = str.replace(/{}/g, "");
        str = str.replace(/["'\[]]/g, "");
        if (str.length === perviousLenght) {
            return false;
        }
    }
    return true;
}
console.log("Good Values ==>");
console.log(isBalanced("[()]"));
console.log(isBalanced("(function(){return [new Bears()]}());"));
console.log(isBalanced("var a = function(){return 'b';}"));
console.log(isBalanced("//Complex object;\n a = [{a:1,b:2,c:[ new Car( 1, 'black' ) ]}]"));
console.log("Bad Values ==>");
console.log(isBalanced("{"));
console.log(isBalanced("{]"));
console.log(isBalanced("{}("));
console.log(isBalanced("({)()()[][][}]"));
console.log(isBalanced("(function(){return [new Bears()}())];"));
console.log(isBalanced("var a = [function(){return 'b';]}"));
console.log(isBalanced("/*Comment: a = [} is bad */var a = function({)return 'b';}"));
console.log(isBalanced("/*[[[ */ function(){return {b:(function(x){ return x+1; })'c')}} /*_)(([}*/"));
console.log(isBalanced("//Complex object;\n a = [{a:1,b:2,c:[ new Car( 1, 'black' ) ]]"));

答案 7 :(得分:0)

JavaScript 中的简单解决方案

时间复杂度 O(n)

/**
 * @param {string} s
 * @return {boolean}
 */
var checkParanthesis = function(s) {
    if(typeof s !== "string" || s.length % 2 !== 0) return false;
    let i = 0;
    let arr = [];
    while(i<s.length) {
        if(s[i]=== "{" || s[i]=== "(" || s[i]=== "[") {
           arr.push(s[i]);
        } else if(s[i] === "}" && arr[arr.length-1] === "{") {
            arr.pop()
        } else if(s[i] === ")" && arr[arr.length-1] === "(") {
            arr.pop()
        } else if(s[i] === "]" && arr[arr.length-1] === "[") {
            arr.pop()
        } else {
            return false;
        }
        i++
    }
    return arr.length === 0;
};
let str = "{([])}";
console.log(checkParanthesis(str))