给定大小为N的字符串S (仅由“(”和“)”组成)和正整数K ,任务是通过将字符串S的任何字符移至任一字符串来检查给定的字符串可以成为有效的括号序列字符串末尾最多K次。
例子:
Input: S = “)(“, K = 1
Output: Yes
Explanation: Move S[0] to the end of the string.
Now, the modified string S is “()” which is balanced. Therefore, the number of moves required is 1( = K).
Input: S = “()()”, K = 0
Output: Yes
方法:可以根据以下观察结果解决给定问题:
- 如果N为奇数或左括号和右括号的数目不相等,则不可能形成有效的括号序列。
- 想法是遍历给定的序列并跟踪开括号和闭括号的计数差,如果该差在任何索引处变为负数,则在当前索引之后移动一些开括号并将其移到开头。
请按照以下步骤解决问题:
- 如果N为奇数或左括号和右括号的数目不相等,则不可能形成有效的括号序列。因此,打印“否” 。否则,请执行以下步骤:
- 将两个变量(例如count和ans)初始化为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)