根据给定条件确定最大 1s 的子序列的最小步骤
给定一个大小为N的字符串S ,由 '0'、'1' 和 '?' 组成,其中N总是偶数。将字符串分成两个不同的字符串,例如S1和S2 ,其中S1将仅包含S的偶数索引处的字符,而S2将仅包含S奇数索引处的字符。任务是找到预测两个字符串S1和S2中哪一个的最大计数为 1 所需的最小可能步骤。在一个步骤中,为S1或S2选择一个字符。如果字符为“ 0 ”则选择“ 0 ”,如果字符为“ 1 ”则选择“ 1 ”,如果字符为“ ? '然后选择' 1 '或' 0 '中的任何一个。
例子:
Input: s = “?10?0?”
Output: 4
Explanation:
Step 1: For S1 character to choose is S[0]=’?’, so choose ‘0’. S1=”0″, S2=””.
Step 2: For S2 character to choose is S[1]=’1′, so choose ‘1’. S1=”0″, S2=”1″.
Step 1: For S1 character to choose is S[2]=’?’, so choose ‘0’. S1=”00″, S2=”1″.
Step 1: For S1 character to choose is S[3]=’?’, so choose ‘1’. S1=”00″, S2=”11″.
After Step 4, S2 will have more number of 1’s irrespective of what number is chosen for the remaining indexes.
Input: s = “?1?0??0110”
Output: 7
方法:这个想法是递归地解决问题,并在探索所有可能的结果后回答这个问题。现在,要解决此问题,请按照以下步骤操作:
- 创建一个名为minSteps的函数,其参数为字符串S ,指针i将指向字符串中的当前位置,直到字符串被分割为止,整数count1和count2将分别存储直到i在S1和S2中的个数,整数first和second用于存储S1和S2中未选择任何值的可用位置,以及表示字符串S大小的整数n 。此函数将返回预测答案所需的最小步骤。
- 现在最初,当前指针为零,因此i=0 。由于到目前为止没有为S1和S2选择任何值,并且S1和S2中的所有位置都可以填充,因此count1=0 、 count2=0 、 first = n/2和second=n/2 。因此,现在使用这些参数调用函数minSteps 。
- 在函数minSteps的每次调用中:
- 检查基本情况,即:
- 如果i达到n (即i=n ),因为这意味着S1和S2都已完全填充,现在可以肯定地预测答案。所以,返回 0。
- 如果count1变得大于second和count2之和,则 返回 0,因为现在,即使在为S2中的可用位置选择了所有位置之后, S1也会有更多的位置。
- 如果count2变得大于first和count1之和,则 由于上述原因,返回 0。
- 检查基本情况后,检查i是偶数还是奇数。如果i是偶数,则该索引由S1选择,否则为S2 。
- 因此,根据当前正在填充的字符串减少第一个或第二个,因为该字符串中的可用位置将在填充后减少一个位置。
- 现在如果当前字符是 '?' (即s[i] = '?' )然后进行选择'1'和选择'0'的递归调用,并在将1加到它们之后返回两者中的最小值。
- 否则,请拨打一个电话并在添加一个电话后返回答案。
- 检查基本情况,即:
- 最后的递归调用将给出这个问题的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
//// Recursive function to minimum steps
// required after combining two strings
int minSteps(string& S, int i, int count1, int count2,
int first, int second, int n)
{
// If current pointer reaches the end
if (i == n) {
return 0;
}
// Condition to conclude that one string does
// more ones than the other irrespective of what
// number is chosen for the remaining indexes
if (count1 > (second + count2)
|| count2 > (first + count1)) {
return 0;
}
int c1 = 0, c2 = 0;
// If i is even, then choosing character for S1
if (i % 2 == 0) {
if (S[i] == '?') {
return min(
1
+ minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n),
1
+ minSteps(
S, i + 1, count1, count2,
first - 1, second, n));
}
else if (S[i] == '1') {
c1 = 1
+ minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n);
return c1;
}
else {
c2 = 1
+ minSteps(
S, i + 1,
count1, count2,
first - 1, second, n);
return c2;
}
}
// If i is odd
else {
if (S[i] == '?') {
return min(
1
+ minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n),
1
+ minSteps(
S, i + 1,
count1, count2,
first, second - 1, n));
}
else if (S[i] == '1') {
c1 = 1
+ minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n);
return c1;
}
else {
c2 = 1
+ minSteps(
S, i + 1, count1,
count2, first,
second - 1, n);
return c2;
}
}
}
// Driver Code
int main()
{
string s = "?10?0?";
int N = s.size();
cout << minSteps(s, 0, 0, 0,
N / 2, N / 2, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG
{
//// Recursive function to minimum steps
// required after combining two strings
static int minSteps(String S, int i, int count1, int count2,
int first, int second, int n)
{
// If current pointer reaches the end
if (i == n) {
return 0;
}
// Condition to conclude that one string does
// more ones than the other irrespective of what
// number is chosen for the remaining indexes
if (count1 > (second + count2)
|| count2 > (first + count1)) {
return 0;
}
int c1 = 0, c2 = 0;
// If i is even, then choosing character for S1
if (i % 2 == 0) {
if (S.charAt(i) == '?') {
return Math.min(
1
+ minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n),
1
+ minSteps(
S, i + 1, count1, count2,
first - 1, second, n));
}
else if (S.charAt(i) == '1') {
c1 = 1
+ minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n);
return c1;
}
else {
c2 = 1
+ minSteps(
S, i + 1,
count1, count2,
first - 1, second, n);
return c2;
}
}
// If i is odd
else {
if (S.charAt(i) == '?') {
return Math. min(
1
+ minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n),
1
+ minSteps(
S, i + 1,
count1, count2,
first, second - 1, n));
}
else if (S.charAt(i) == '1') {
c1 = 1
+ minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n);
return c1;
}
else {
c2 = 1
+ minSteps(
S, i + 1, count1,
count2, first,
second - 1, n);
return c2;
}
}
}
// Driver code
public static void main (String[] args)
{
String s = "?10?0?";
int N = s.length();
System.out.println(minSteps(s, 0, 0, 0,
N / 2, N / 2, N));
}
}
// This code is contributed by sanjoy_62.
Python3
# Python code for the above approach
import math
# Recursive function to minimum steps
# required after combining two strings
def minSteps(S, i, count1, count2,
first, second, n):
# If current pointer reaches the end
if i == n:
return 0
# Condition to conclude that one string does
# more ones than the other irrespective of what
# number is chosen for the remaining indexes
if count1 > second + count2 or count2 > first + count1:
return 0
c1 = 0
c2 = 0
# If i is even, then choosing character for S1
if i % 2 == 0:
if S[i] == '?':
return min(
1 + minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n),
1 + minSteps(
S, i + 1, count1, count2,
first - 1, second, n))
elif S[i] == '1':
c1 = 1 + minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n)
return c1
else:
c2 = 1 + minSteps(
S, i + 1,
count1, count2,
first - 1, second, n)
return c2
# If i is odd
else:
if S[i] == '?':
return min(
1 + minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n),
1 + minSteps(
S, i + 1,
count1, count2,
first, second - 1, n))
elif S[i] == '1':
c1 = 1 + minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n)
return c1
else:
c2 = 1 + minSteps(
S, i + 1, count1,
count2, first,
second - 1, n)
return c2
# Driver Code
s = "?10?0?"
N = len(s)
print(minSteps(s, 0, 0, 0,
math.floor(N / 2), math.floor(N / 2), N))
# This code is contributed by Potta Lokesh
C#
// C# program for the above approach
using System;
class GFG
{
//// Recursive function to minimum steps
// required after combining two strings
static int minSteps(string S, int i, int count1, int count2,
int first, int second, int n)
{
// If current pointer reaches the end
if (i == n) {
return 0;
}
// Condition to conclude that one string does
// more ones than the other irrespective of what
// number is chosen for the remaining indexes
if (count1 > (second + count2)
|| count2 > (first + count1)) {
return 0;
}
int c1 = 0, c2 = 0;
// If i is even, then choosing character for S1
if (i % 2 == 0) {
if (S[i] == '?') {
return Math.Min(
1
+ minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n),
1
+ minSteps(
S, i + 1, count1, count2,
first - 1, second, n));
}
else if (S[i] == '1') {
c1 = 1
+ minSteps(
S, i + 1,
count1 + 1, count2,
first - 1, second, n);
return c1;
}
else {
c2 = 1
+ minSteps(
S, i + 1,
count1, count2,
first - 1, second, n);
return c2;
}
}
// If i is odd
else {
if (S[i] == '?') {
return Math.Min(
1
+ minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n),
1
+ minSteps(
S, i + 1,
count1, count2,
first, second - 1, n));
}
else if (S[i] == '1') {
c1 = 1
+ minSteps(
S, i + 1,
count1, count2 + 1,
first, second - 1, n);
return c1;
}
else {
c2 = 1
+ minSteps(
S, i + 1, count1,
count2, first,
second - 1, n);
return c2;
}
}
}
// Driver code
public static void Main ()
{
string s = "?10?0?";
int N = s.Length;
Console.Write(minSteps(s, 0, 0, 0,
N / 2, N / 2, N));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
4
时间复杂度: O(2^N)
辅助空间: O(1)