-1

Here is the question: A bracket sequence is called regular if it is possible to obtain correct arithmetic expression by inserting characters + and 1 into this sequence. For example, sequences (())(), () and (()(())) are regular, while )(, (() and (()))( are not. Let's call a regular bracket sequence "RBS".

You are given a sequence s of n characters (, ), and/or ?. There is exactly one character ( and exactly one character ) in this sequence.

You have to replace every character ? with either ) or ( (different characters ? can be replaced with different brackets). You cannot reorder the characters, remove them, insert other characters, and each ? must be replaced.

Determine if it is possible to obtain an balanced sequence or not after these replacements.

EX:

5
()
(?)
(??)
??()
)?(?

Output:

YES
NO
YES
YES
NO

Here is my code:

#include <bits/stdc++.h>
using namespace std;

bool checkValidString(string s) {
    stack<char>st;
    for(int i=0;i<s.length();i++)
    {
        if(!st.empty() && (((st.top() == '(') && s[i] == '?') || ((st.top() == '?') && s[i] == ')') || st.top() == '(' && s[i] == ')'))
        {
            st.pop();
        }
        else
        {
            st.push(s[i]);
        }
    }
    if(st.empty())
    {
      return true;
    }
    int si = st.size();
    bool odd = false;
    if(si%2!=0)
    {
      odd = true;
    }
    while(!st.empty())
    {
        char c = st.top();
        if(c!='?')
        {
            return false;
        }
        st.pop();
    }
    if(odd)
    {
        return false;
    }
    return true;
}

int main() {
    // your code goes here
    int n;
    cin>>n;
    while(n--)
    {
        string s;
        cin>>s;
        bool ans = checkValidString(s);
        if(ans == 1)
        {
            cout<<"YES"<<endl;
        }
        else
        {
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

However it is giving wrong answer,Can you help where I am going wrong?Thanks.

Deepak Tatyaji Ahire
  • 4,241
  • 2
  • 9
  • 27

2 Answers2

3

This kind of problem won't work by the logic for checking valid parenthesis.

Example: The test case where input string = (?)? will fail in your case. But it is a valid string as it can take the form (()).

So now, how do you approach such a problem?

Let's figure out what are all the possible input strings can look like.

Test Cases:

  1. If number if question marks are odd, then it's an invalid string.
  2. If Opening bracket appears before closing one, and we have odd number of question marks between them:

(???)? or ?(???) => Both are valid strings, as they can take the form ((())).

  1. If Opening bracket appears before closing one, and we have even number of question marks between them:

(????) or ??(??)?? => These kind of strings are always valid.

  1. If Opening parenthesis comes closing parenthesis:

?)(? => This string is also valid as it can take the from ()().

  1. The only thing we need to worry about is if ) is the first position or ( is at the last position:

)??( => Always an invalid string.

)?(? => Always an invalid string.

?)?( => Always an invalid string.

Therefore, the problem gets simplified to 3 main conditions:

  1. The length of the string should be even: For this to be true, the number of ? characters in the string should be even.

  2. The string should not start with ).

  3. The string should not end with (.

Have a look at the following code which has Accepted status on Codeforces:

#include <iostream>
#include <string>

int main(){
    
    int t;
    scanf("%d", &t);
    
    while(t--){
        
        std::string s;
        std::cin>>s;
        
        int len = s.length();
        int countQuestion = 0;
        
        for(int i=0;i<len;i++){
            
            if(s[i]=='?'){
                countQuestion++;
            }
        }    
        
        //Check 1: If question count is even?
        if(countQuestion & 1){
            
            printf("NO\n");
        }else{
            
            if(s[0] == ')' || s[len-1] == '('){
                printf("NO\n");
            }else{
                printf("YES\n");
            }
        }
    }
    
    return 0;
}

Verdict:

enter image description here

Deepak Tatyaji Ahire
  • 4,241
  • 2
  • 9
  • 27
0

If you wanted to check a string of brackets to see if it was valid, you'd keep a counter of open brackets as you walk through the string. You'd start it at 0, increment it for every ( and decrement it for every ). You'd check to make sure that it never goes negative and that it ends at 0.

If some of the brackets are replaced by question marks, you can imagine doing the same thing, but at every position you can calculate all the possible non-negative values of the counter. If that set of values ever goes empty, then a valid bracket string is impossible. If that set doesn't include 0, then a valid bracket string is impossible.

It turns out (and you can prove by induction), that the set of possible values always includes every 2nd number between two numbers x and y.

After ?, [x,y] -> [x-1,y+1], excluding numbers < 0

After (, [x,y] -> [x+1,y+1]

After ), [x,y] -> [x-1,y-1], excluding numbers < 0

So you can test any sequence of brackets and question marks by running through the string, starting with [0,0] and modifying the range according to the above rules for each character. Make sure it never goes empty and includes 0 at the end.

bool checkValidString(string s) {
    int l=0, h=0;
    for(int i=0;i<s.length();i++) {
        switch(s[i]) {
            case '(':
            ++l;++h;
            break;

            case ')':
            if (h<=0) {
                return false;
            }
            --h;
            l += (l>0 ? -1:1);
            break;

            default:
            ++h;
            l += (l>0 ? -1:1);
            break;
        }
    }
    return l==0;
}
Matt Timmermans
  • 45,884
  • 3
  • 35
  • 76