打印所有可以通过替换通配符“?”形成的平衡括号字符串


平衡括号是指,如果我们有一串括号,则每个开括号都有一个对应的闭括号,并且括号对是正确嵌套的。字符串的大小应该是偶数。在这个问题中,我们给定了一个也包含字符“?”的括号字符串,我们的任务是通过将“?”替换为合适的括号来形成所有可能的平衡括号字符串。在给定的字符串中,只使用了圆括号“(”和“)”。

示例

Input 1: str = “()(?)?”
Output 1: ()(()) 

解释

只有一种可能的平衡字符串可以通过替换“?”来形成。

Input 2: str = “??????”
Output 2: ((()))
(()())
(())()
()(())
()()()

解释

有两种可能的方法可以形成一个平衡字符串。

  • 一种方法是用开括号替换索引 0、1 和 2,用闭括号替换其他索引。

  • 第二种方法是用开括号替换索引 0、1 和 3,用闭括号替换其他索引。

  • 第三种方法是用开括号替换索引 0、1 和 4,用闭括号替换其他索引。

  • 第四种方法是用开括号替换索引 0、2 和 3,用闭括号替换其他索引。

  • 最后一种方法是用开括号替换索引 0、2 和 4,用闭括号替换其他索引。

方法

我们已经看到了上面给定字符串的示例,让我们来看一下方法 -

我们可以使用回溯法来解决这个问题。

让我们在下面讨论这种方法 -

  • 首先,我们将初始化一个名为“create”的函数,以在替换“?”后创建所有可能的字符串,参数为 str 和 index = 0。

  • 在函数中,

  • −> 首先,我们设置基本条件。如果我们到达了字符串的终点,那么我们必须将该字符串传递给“check”函数以验证该字符串是否平衡。如果它平衡,则打印字符串。

    −>如果字符串的当前字符是“?”,

    首先,用开括号替换它,并调用相同的函数以检查我们是否到达了字符串的末尾。

    其次,用闭括号替换它,并再次调用相同的函数以检查我们是否到达了字符串的末尾。

    最后,我们回溯字符串并将当前字符赋值为“?”

    −>否则,字符串的当前字符是一个括号,然后通过调用相同的函数移动到下一个索引。

  • 初始化“check”函数以验证字符串是否平衡。

  • −> 在此函数中,我们初始化堆栈,然后检查

    −> 如果字符串的第一个字符是闭括号,则返回 false

    −> 否则如果当前括号是闭括号,则还有两个条件:如果堆栈为空则返回 false,因为在对应的开括号中。否则从堆栈中弹出对应的开括号。

    −> 最后,我们检查了如果堆栈为空,则表示字符串是平衡的并返回 true,否则还有一些括号剩余,则表示字符串不平衡并返回 false。

示例

以下是上述回溯方法的 C++ 代码,用于获取所有平衡字符串

#include <bits/stdc++.h>
using namespace std; 
// Function 'check' to verify whether the string is balanced or not
bool check(string str){
   stack<char> S; // created stack 
   
// If the first character of the string is a close bracket, then return false
   if (str[0] == ')') {
      return false;
   } 
   
   // Traverse the string using for loop 
   for (int i = 0; i < str.size(); i++) { 
   
      // If the current character is an open bracket, then push it into the stack
      if (str[i] == '(') { 
         S.push('(');
      } 
      
      // If the current character is a close bracket
      else { 
      
         // If the stack is empty, there is no corresponding open bracket return false
         if (S.empty()){
            return false;
         }
         
         // Else pop the corresponding opening bracket from the stack
         else
            S.pop();
      }
   } 
   
   // If the stack is empty, return true
   if (S.empty()){
      return true;
   }
   else {
      return false;
   }
} 

// Function 'create' to create all possible bracket strings
void create(string str, int i){ 

   // If reached the end of the string
   if (i == str.size()) { 
   
      // passed 'str' to the 'check' function to verify whether the string is balanced or not
      if (check(str)) { 
      
         // If it is a balanced string
         cout<< str << endl; // print the string
      }
      return; 
   } 
   
   // If the current character of the string is '?'
   if (str[i] == '?') { 
      str[i] = '('; // replace ? with (
      create(str, i + 1); // continue to next character 
      str[i] = ')'; // replace ? with )
      create(str, i + 1); // continue to next character 
      
      // backtrack
      str[i] = '?';
   }
   
   // If the current character is bracketed then move to the next index
   else {
      create(str, i + 1);
   }
} 
int main(){
   string str = "??????"; //given string 
   
   // Call the function
   create (str, 0);
   return 0;
}

输出

((()))
(()())
(())()
()(())
()()()

时间和空间复杂度

上面代码的时间复杂度为 O(N*(2^N),因为我们必须回溯字符串。

上面代码的空间复杂度为 O(N),因为我们将括号存储在堆栈中。

其中 N 是字符串的大小。

结论

在本教程中,我们实现了一个程序来打印所有可以通过替换通配符“?”形成的平衡括号字符串。我们实现了回溯方法。时间复杂度为 O(N*(2^N),空间复杂度为 O(N)。其中 N 是字符串的大小。

更新于: 2023-07-26

152 次查看

开启你的 职业生涯

通过完成课程获得认证

立即开始
广告

© . All rights reserved.