📜  通过将括号最多移到任意一端两次来检查是否有可能获得平衡括号

📅  最后修改于: 2021-04-17 17:32:41             🧑  作者: Mango

给定大小为N的字符串S (仅由“(”“)”组成)和正整数K ,任务是通过将字符串S的任何字符移至任一字符串来检查给定的字符串可以成为有效的括号序列字符串末尾最多K次。

例子:

方法:可以根据以下观察结果解决给定问题:

  • 如果N为奇数或左括号和右括号的数目不相等,则不可能形成有效的括号序列。
  • 想法是遍历给定的序列并跟踪开括号和闭括号的计数,如果该在任何索引变为负数,则在当前索引之后移动一些开括号并将其移到开头。

请按照以下步骤解决问题:

  • 如果N为奇数或左括号和右括号的数目不相等,则不可能形成有效的括号序列。因此,打印“否” 。否则,请执行以下步骤:
  • 将两个变量(例如countans)初始化为0 ,以分别跟踪开括号和闭括号的差异以及所需的移动次数。
  • 遍历给定的字符串S并执行以下步骤:
    • 如果当前字符S [i]为’ ( ‘,则将count的值增加1
    • 否则,将count的值减1
    • 如果计数小于0 ,则将计数更新为0 ,并将ans的值增加1
  • 完成上述步骤后,如果ans的值最多为K ,则打印“是” 。否则,打印“否”

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to check if a valid parenthesis
// can be obtained by moving characters
// to either end at most K number of times
void minimumMoves(string s, int n, int k)
{
    // Base Case 1
    if (n & 1) {
        cout << "No";
        return;
    }
 
    // Count of '(' and ')'
    int countOpen = count(s.begin(),
                          s.end(), '(');
    int countClose = count(s.begin(),
                           s.end(), ')');
 
    // Base Case 2
    if (countOpen != countClose) {
        cout << "No";
        return;
    }
 
    // Store the count of moves required
    // to make a valid parenthesis
    int ans = 0;
    int cnt = 0;
 
    // Traverse the string
    for (int i = 0; i < n; ++i) {
 
        // Increment cnt if opening
        // bracket has occurred
        if (s[i] == '(')
            ++cnt;
 
        // Otherwise, decrement cnt by 1
        else {
 
            // Decrement cnt by 1
            --cnt;
 
            // If cnt is negative
            if (cnt < 0) {
 
                // Update the cnt
                cnt = 0;
 
                // Increment the ans
                ++ans;
            }
        }
    }
 
    // If ans is at most K, then
    // print Yes. Otherwise print No
    if (ans <= k)
        cout << "Yes";
    else
        cout << "No";
}
 
// Driver Code
int main()
{
    string S = ")(";
    int K = 1;
    minimumMoves(S, S.length(), K);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
// Function to check if a valid parenthesis
// can be obtained by moving characters
// to either end at most K number of times
static void minimumMoves(String s, int n, int k)
{
     
    // Base Case 1
    if (n % 2 == 1)
    {
        System.out.println("No");
        return;
    }
 
    // Count of '(' and ')'
    int countOpen = 0, countClose = 0;
    for(char ch : s.toCharArray())
        if (ch == '(')
            countOpen++;
        else if (ch == ')')
            countClose++;
 
    // Base Case 2
    if (countOpen != countClose)
    {
        System.out.println("No");
        return;
    }
 
    // Store the count of moves required
    // to make a valid parenthesis
    int ans = 0;
    int cnt = 0;
 
    // Traverse the string
    for(int i = 0; i < n; ++i)
    {
         
        // Increment cnt if opening
        // bracket has occurred
        if (s.charAt(i) == '(')
            ++cnt;
 
        // Otherwise, decrement cnt by 1
        else
        {
             
            // Decrement cnt by 1
            --cnt;
 
            // If cnt is negative
            if (cnt < 0)
            {
                 
                // Update the cnt
                cnt = 0;
 
                // Increment the ans
                ++ans;
            }
        }
    }
 
    // If ans is at most K, then
    // print Yes. Otherwise print No
    if (ans <= k)
        System.out.println("Yes");
    else
        System.out.println("No");
}
 
// Driver Code
public static void main(String[] args)
{
    String S = ")(";
    int K = 1;
     
    minimumMoves(S, S.length(), K);
}
}
 
// This code is contributed by Kingash


输出:
Yes

时间复杂度: O(N)
辅助空间: O(1)