给定一个大小为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 ,则打印“Yes” 。否则,打印“否” 。
下面是上述方法的实现:
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
Python3
# python 3 program for the above approach
# Function to check if a valid parenthesis
# can be obtained by moving characters
# to either end at most K number of times
def minimumMoves(s, n, k):
# Base Case 1
if (n & 1):
print("No")
return
# Count of '(' and ')'
countOpen = s.count('(')
countClose = s.count(')')
# Base Case 2
if (countOpen != countClose):
print("No")
return
# Store the count of moves required
# to make a valid parenthesis
ans = 0
cnt = 0
# Traverse the string
for i in range(n):
# Increment cnt if opening
# bracket has occurred
if (s[i] == '('):
cnt += 1
# Otherwise, decrement cnt by 1
else:
# Decrement cnt by 1
cnt -= 1
# If cnt is negative
if (cnt < 0):
# Update the cnt
cnt = 0
# Increment the ans
ans += 1
# If ans is at most K, then
# print Yes. Otherwise print No
if (ans <= k):
print("Yes")
else:
print("No")
# Driver Code
if __name__ == "__main__":
S = ")("
K = 1
minimumMoves(S, len(S), K)
# This code is contributed by ukasp.
C#
// C# program for the above approach
using System;
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)
{
Console.WriteLine("No");
return;
}
// Count of '(' and ')'
int countOpen = 0, countClose = 0;
foreach(char ch in s.ToCharArray())
if (ch == '(')
countOpen++;
else if (ch == ')')
countClose++;
// Base Case 2
if (countOpen != countClose)
{
Console.WriteLine("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)
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
// Driver Code
static void Main()
{
string S = ")(";
int K = 1;
minimumMoves(S, S.Length, K);
}
}
// This code is contributed by SoumikMondal
Javascript
输出:
Yes
时间复杂度: O(N)
辅助空间: O(1)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live