Open In App

Replace ‘?’ in string with zero or one

Last Updated : 02 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary string consisting of 0s and 1s and ‘?’ characters and an integer K, it is allowed to replace ‘?’ with 0 or 1, the task is to check if there is a unique way of replacing ‘?’ with 0s and 1s such that there is only 1 substring of K length containing all 1s. If there is only one way to do so print “Yes” otherwise “No” in all other cases.

Note: There should be only 1 possible position of K length substring of all 1s for the answer to be Yes.

Examples:

Input: S = ?1?0, K = 2
Output: No
Explanation: There are two possible ways which satisfies all the conditons, S = 1100, 0110. Hence due to multiple ways the output would be No.

Input: S = 00?1???10?, K = 5
Output: Yes
Explanation: There is only one possible string S = 0001111100 that have exactly K length substring of all 1s and is the only possible way.

Naive Approach: The basic way to solve the problem is as follows: 

For every K-length substring, we can make that all 1s only if all characters in the substring are ‘1’s or ‘?’s and all other characters outside that substring are all ‘0’s or ‘?’s.
We can check this with brute force for every K-length substring and count the respective number of characters. 

Time complexity: O(|s|K)
Auxiliary Space: O(1)

Efficient-Approach: To solve the problem follow the below idea:

Moving from Si to Si+K we can keep track of the changes. Now keep count of the number of valid ways. If there is only 1 way, then print “Yes” or else “No”.

Steps that were to follow the above approach: 

  • Make two prefix arrays sum and tot where sum[i] stores the number of 0s up to index i and tot[i] stores the number of 1s up to index i respectively in string S. 
  • Now iterate in the range [k, n] where n is the length of string s.
  • To check if we can make a valid substring, we have to check three conditions: (tot[i – k] == 0 and tot[n] – tot[i] == 0 and sum[i] – sum[i – k] == 0)
  • Initialize a variable cnt = 0, to store the number of valid substrings.
  • Whenever we find these three conditions true for a substring increment cnt = cnt + 1. 
  • Check if cnt == 1 at the end. If cnt == 1, then print “Yes” or else “No”.

Below is the implementation of the above approach:

C++




// C++ program for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the given
// string is valid
string isValidString(string s, int k)
{
 
    // Getting size of the string
    int n = s.size();
 
    // Initializing prefix arrays
    vector<int> sum(n + 1, 0);
    vector<int> tot(n + 1, 0);
 
    // Precomputing prefix arrays
    for (int i = 0; i < n; i++) {
        sum[i + 1] += sum[i];
        if (s[i] == '0')
            sum[i + 1]++;
        if (s[i] == '1')
            tot[i + 1]++;
        tot[i + 1] += tot[i];
    }
 
    // Initializing cnt to count total
    // number of valid substrings.
    int cnt = 0;
    for (int i = k; i <= n; i++) {
 
        // Condition for a valid substring
        if (tot[i - k] == 0 and tot[n] - tot[i] == 0
            and sum[i] - sum[i - k] == 0)
 
            // Incrementing cnt to keep
            // track of valid substrings.
            cnt++;
    }
 
    // Returning the answer
    if (cnt == 1)
        return "Yes";
    return "No\n";
}
 
// Driver's code
int main()
{
    string s = "00?1???10?";
    int k = 5;
 
    // Function Call
    cout << isValidString(s, k);
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
public class Main {
 
    // Function to check if the given
    // string is valid
    static String isValidString(String s, int k)
    {
 
        // Getting size of the string
        int n = s.length();
 
        // Initializing prefix arrays
        int[] sum = new int[n + 1];
        Arrays.fill(sum, 0);
        int[] tot = new int[n + 1];
        Arrays.fill(tot, 0);
 
        // Precomputing prefix arrays
        for (int i = 0; i < n; i++) {
            sum[i + 1] += sum[i];
            if (s.charAt(i) == '0')
                sum[i + 1]++;
            if (s.charAt(i) == '1')
                tot[i + 1]++;
            tot[i + 1] += tot[i];
        }
 
        // Initializing cnt to count total
        // number of valid substrings.
        int cnt = 0;
        for (int i = k; i <= n; i++) {
 
            // Condition for a valid substring
            if ((tot[i - k] == 0) && (tot[n] - tot[i] == 0)
                && (sum[i] - sum[i - k] == 0))
 
                // Incrementing cnt to keep
                // track of valid substrings.
                cnt++;
        }
 
        // Returning the answer
        if (cnt == 1)
            return "Yes";
        return "No\n";
    }
 
    // Driver's code
    public static void main(String[] args)
    {
        String s = "00?1???10?";
        int k = 5;
 
        // Function Call
        System.out.println(isValidString(s, k));
    }
}
 
// This code is contributed by Susobhan Akhuli


Python3




# Function to check if the given
# string is valid
def isValidString(s, k):
 
    # Getting size of the string
    n = len(s)
 
    # Initializing prefix arrays
    sum_arr = [0] * (n + 1)
    tot = [0] * (n + 1)
 
    # Precomputing prefix arrays
    for i in range(n):
        sum_arr[i + 1] += sum_arr[i]
        if s[i] == '0':
            sum_arr[i + 1] += 1
        if s[i] == '1':
            tot[i + 1] += 1
        tot[i + 1] += tot[i]
 
    # Initializing cnt to count total
    # number of valid substrings.
    cnt = 0
    for i in range(k, n + 1):
 
        # Condition for a valid substring
        if tot[i - k] == 0 and tot[n] - tot[i] == 0 and sum_arr[i] - sum_arr[i - k] == 0:
 
            # Incrementing cnt to keep
            # track of valid substrings.
            cnt += 1
 
    # Returning the answer
    if cnt == 1:
        return "Yes"
    return "No\n"
 
# Driver's code
if __name__ == '__main__':
    s = "00?1???10?"
    k = 5
 
    # Function Call
    print(isValidString(s, k))
# akashish__


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
    // Function to check if the given
    // string is valid
    static string IsValidString(string s, int k)
    {
        // Getting size of the string
        int n = s.Length;
 
        // Initializing prefix arrays
        List<int> sum = new List<int>(n + 1);
        List<int> tot = new List<int>(n + 1);
        for (int i = 0; i <= n; i++) {
            sum.Add(0);
            tot.Add(0);
        }
 
        // Precomputing prefix arrays
        for (int i = 0; i < n; i++) {
            sum[i + 1] += sum[i];
            if (s[i] == '0')
                sum[i + 1]++;
            if (s[i] == '1')
                tot[i + 1]++;
            tot[i + 1] += tot[i];
        }
 
        // Initializing cnt to count total
        // number of valid substrings.
        int cnt = 0;
        for (int i = k; i <= n; i++) {
            // Condition for a valid substring
            if (tot[i - k] == 0 && tot[n] - tot[i] == 0
                && sum[i] - sum[i - k] == 0) {
                // Incrementing cnt to keep
                // track of valid substrings.
                cnt++;
            }
        }
 
        // Returning the answer
        if (cnt == 1)
            return "Yes";
        return "No\n";
    }
 
    // Driver's code
    public static void Main()
    {
        string s = "00?1???10?";
        int k = 5;
 
        // Function Call
        Console.WriteLine(IsValidString(s, k));
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// Javascript program for the above approach
 
// Function to check if the given
// string is valid
function isValidString(s, k) {
 
    // Getting size of the string
    let n = s.length;
 
    // Initializing prefix arrays
    let sum = Array(n + 1).fill(0);
    let tot = Array(n + 1).fill(0);
 
    // Precomputing prefix arrays
    for (let i = 0; i < n; i++) {
        sum[i + 1] += sum[i];
        if (s[i] == '0')
            sum[i + 1]++;
        if (s[i] == '1')
            tot[i + 1]++;
        tot[i + 1] += tot[i];
    }
 
    // Initializing cnt to count total
    // number of valid substrings.
    let cnt = 0;
    for (let i = k; i <= n; i++) {
 
        // Condition for a valid substring
        if (tot[i - k] == 0 && tot[n] - tot[i] == 0
            && sum[i] - sum[i - k] == 0)
 
            // Incrementing cnt to keep
            // track of valid substrings.
            cnt++;
    }
 
    // Returning the answer
    if (cnt == 1)
        return "Yes";
    return "No\n";
}
 
// Driver's code
let s = "00?1???10?";
let k = 5;
 
// Function Call
console.log(isValidString(s, k));
 
// This code is contributed by Susobhan Akhuli


Output

Yes

Time Complexity: O(|s|)
Auxiliary Space: O(|s|)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads