【问题标题】:Find index k at which the number of opening and closing brackets is the same找到左括号和右括号的数量相同的索引 k
【发布时间】:2017-06-04 18:44:48
【问题描述】:

我遇到了这个问题,但无法解决。
任务是在一串左/右括号中找到一个合适的索引,其中前 k 个字符中的左括号数 = 剩余 N-k 个字符中的右括号数。
前任。

"(()))))(" k 将是 5,因为前 5 个字符 "(()))" 有 2 左括号,其余的 "))(" 有 2 个右括号。

另一个例子:

"()))()" k 为 4。

k 是唯一的。解应该是 O(N)。

【问题讨论】:

  • 我凭直觉认为,k=右括号的数量。 :-)

标签: string algorithm performance


【解决方案1】:

使用两个索引分别指向第一个和最后一个字符。

当两个索引没有相互交叉时,将它们移动如下:

  • 如果左侧索引处的字符不是“(”,则递增;
  • 如果右侧索引处的字符不是“)”,则将其递减;
  • 如果以上都不是,则同时增加左侧索引并减少右侧索引

返回左边的索引。

这是 JavaScript 中的一个实现,它运行您给出的两个示例的算法:

function partition(s) {
    var i = 0;
    var j = s.length - 1;
    while (i <= j) {
        if (s[i] !== '(') {
            i++;
        } else if (s[j] !== ')') {
            j--;
        } else {
            i++;
            j--;
        }
    }
    return i;
}

console.log(partition("(()))))("));
console.log(partition("()))()"));

随着循环的每次迭代中索引越来越接近,最多有 n 次迭代。

【讨论】:

    【解决方案2】:

    在预处理阶段,您可以计算字符串中的所有右括号(我们称之为c)。然后你处理从左边开始的每个字符。让我们用seenOpening 表示已处理的左括号数,用unseenClosing 表示您尚未处理的右括号数。最初是 seenOpening = 0unseenClosing = c。处理完每个字符后,根据括号类型增加seenOpening 或减少unseenClosing。每当seenOpening == unseenClosing 终止并返回您处理的最后一个字符的索引。

    【讨论】:

      【解决方案3】:

      这是一个 Java 解决方案:

      public int getIndexOnMatchingBracketCount(String str) { 
          int closingBracket = 0;
          int openingBracket = 0;
      
          for (int i = 0; i < s.length(); i++) {
              char c = s.charAt(i);
              if (c == ')') {
                  closingBracket++;
              }
          }
      
          for (int i = 0; i < s.length(); i++) {
              if (openingBracket == closingBracket) {
                  return i;
              }
      
              char c = s.charAt(i);
              if (c == ')') {
                  closingBracket--;
              } else if (c == '(') {
                  openingBracket++;
              }
          }
      
          return -1
      }
      

      【讨论】:

        【解决方案4】:

        如果允许我们使用O(n) 空间,我们可以在O(n) 中以最少的逻辑轻松做到这一点(如下图python 所示):

        def find_index(str):
        
            n = len(str) 
            # O(n) space: no. of '(' in first k+1 and no. of ')' in last n-k characters
            opening_in_first_k, closing_in_last_n_k = [0]*n, [0]*n 
        
            for i in range(1, n): # O(n) time
                opening_in_first_k[i], closing_in_last_n_k[n-1-i] = opening_in_first_k[i-1] + (str[i] == '('), \
                                                                    closing_in_last_n_k[n-i] + (str[n-1-i] == ')')
            for i in range(n): # O(n) time
                if opening_in_first_k[i] == closing_in_last_n_k[i+1]:
                    return i
        
            return -1
        
        print find_index("(()))))(")
        # 5
        print find_index("()))())")
        # 4
        

        【讨论】:

        • 或者,更简单:return str.count(')')
        猜你喜欢
        • 1970-01-01
        • 2012-02-25
        • 2019-02-03
        • 1970-01-01
        • 2017-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多