简体   繁体   中英

Parentheses change O(n) algorithm

If I have a n length string of open ( and close ) parentheses and I have to count the number of time I change the close ) parentheses to open ( every time when I have more close parentheses than the open one at the current moment while traversing from left to right in every substring of that string.

For eg : n = 3, s = ) ( ) :

all substring of s will be [ ), ) (, ) ( ), (, ( ), ) ]

we will have to count in all substring, like in ) ( ) we have close = 1 and open = 0, close > open hence count++. Now the currently processed string is ( ( ) , and have no more change to do. Similarly, when we do this for all substring count will be 4.

I wrote a brute force code. I'm assuming is there any way to do this using stack or dynamic programming to do in O(n) or something?

My brute force is like : 1. Create every substring of the given string. O(n^2). 2. Iterating through one substring at a time to count the change. O(n) Hence, total complexity is O(n^3)

The O annotation is not taking into account things like your bookkeeping/state variables etc. It is only related to how often the input data has to be processed. If I understood your task right, you just need to loop a single time through every character. Since during that single loop there is no information available to you that tells you something about characters further down the line, you have absolutely no choice than to loop through the entire string a single time. Therefore O(N) is the best possible complexity for this task.

If your "bruteforce code" loops more than once (aka is not O(N)), post it here and people will look.

The problem can be solved in O(n^2) by doing some precomputation. Take two arrays left and right of size n(string length). left[index] will store no of left parentheis from s[0] to s[index], similarly right will store no of right parenthesis. So for your example s = ")()" , left will be [0, 1, 1] and right will be [1, 1, 2]. This precomputation can be done in O(n). Now we need to figure out how many left parenthesis should have been added for each interval (i,j). So for each interval and sum them up. For each interval figure out this value using the precomputed array in O(1). To iterate each interval we need O(n^2). So the overall complexity is O(n^2).

int main(){
    vector<int>prefix_sum_left_parentheisis(1000, 0);
    vector<int>prefix_sum_right_parentheisis(1000, 0);
    string s = ")()";
    int count_left_parenthesis = 0;
    int count_right_parenthesis = 0;

    int index = 0;
    for(auto ch:s) {
        if(ch=='(')
            count_left_parenthesis++;
        else
            count_right_parenthesis++;

        prefix_sum_left_parentheisis[index] = count_left_parenthesis;
        prefix_sum_right_parentheisis[index] = count_right_parenthesis;
        index++;
    }

    auto total = 0;
    for(auto i = 0; i < s.size(); i++) {
        for(auto j = i; j < s.size(); j++) {
            if(i == 0) {
                total += max(0, prefix_sum_right_parentheisis[j] - prefix_sum_left_parentheisis[j]);
            }
            else {
                auto count_left_parenthesis_in_range = prefix_sum_left_parentheisis[j] - prefix_sum_left_parentheisis[i-1];
                auto count_right_parenthesis_in_range = prefix_sum_right_parentheisis[j] - prefix_sum_right_parentheisis[i-1];
                total += max(0,count_right_parenthesis_in_range - count_left_parenthesis_in_range);
            }
        }
    }
    cout << "answer is: " << total;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM