问题
Find an algorithm to recursively remove all adjacent duplicates in a given string this is the original question.I have thought of an algorithm using stacks.
1.Initialize a stack and a char_popped variable
2.Push the first char of str into the stack.
3.now iterate through the characters of string.
if the top of stack matches with the character
{
pop the character from the stack,
char_popped=character
}
else
{
if(character==char_popped)
{DONT DO ANYTHING}
else
push the character on the stack
char_popped=null
}
Whatever is remaining on stack is the resultant string.
Auxillary space :O(n) Complexity : O(n)
Is this a correct solution and canyone explain the o(n) solution explained in the post?
回答1:
Is this a correct solution
Yes it is. Let me try to sanitize your idea of using stacks taking into account what @rici mentioned.
You want to traverse through the characters of the string once. This is how your algorithm flows:
1. Initialize a stack containing the string. (Stack A)
2. Pop top most element of Stack A and push into Stack B thereby initializing Stack B
3. Pop from Stack B and pop from Stack A and check if they are equal.
4. If they aren't push both the elements in Stack B. (The popped element from Stack A is pushed later to preserve order)
5. Do step 3 till Stack A is empty.
Stack B should contain the chracters with adjacent duplicates removed.
The above algorithm is clearly O(N)
because at every step 3, we are definitely popping an element off Stack A and therefore the size of Stack A goes down by 1 after every step 3.
canyone explain the o(n) solution explained in the post?
Coming to the recursive algorithm that you wanted to get a hang on. This is how it goes:
At any point in time the function removeUtil
has two values - one is the character array str
from which we have to remove adjacent duplicates and the other is the character last_removed
.
Pseudo code with some description -
1. It checks if the first two characters of the str are same, if they are:
update last_removed and call removeUtil again on the remaining characters
(hence the str ++)
2. If first two characters are not same, we do the same exercise as in 1
only this time we start from str[1], hence removeUtil(str+1, last_removed);
3. Now the returned value from call in 2 is stored in a rem_str because we have
characters that didn't match like str[0] in 2 that are orphan and need to be appended
in the final array just like we pushed elements into the stack in your case.
4. Let's assume the string is 'abbac'-
In the first call we reach here -> removeUtil("bbac", '\0');
str[0] -> 'a'
Now this call -> removeUtil("bbac", '\0'); returns "ac"
and when the recursion unfolds at this point rem_str -> "ac"
str[0] -> 'a'
Hence this :
if (rem_str[0] && rem_str[0] == str[0])
{
*last_removed = str[0];
return (rem_str+1); // In our case this would return "c" to the previous function call
}
5. if (rem_str[0] == '\0' && *last_removed == str[0])
return rem_str;
Consider the string they mention -> "acbbcddc"
So at some point we have situation where:
this call happens-> removeUtil("bbcddc", '\0');
followed by -> removeUtil("cddc", 'b');
followed by -> removeUtil("ddc", 'b');
followed by -> removeUtil("c", 'd');
That returns 'c' and considering the str[0] in the string "cddc" , it goes to case 4
and therefore 'c' gets removed returning an empty string and last_removed -> 'c'.
So removeUtil("bbcddc", '\0'); returns an empty string with last_removed -> 'c'.
However, here str[0] is the same as the last_removed character and therefore should be removed.
6. If none of the following string matches that means str[0] should be appended to final answer.
rem_str--;
rem_str[0] = str[0];
return rem_str;
And here also since we are traversing the character array and 'forming' the final character array that get returned by appropriately appending and removing characters, the time complexity is O(N)
.
Sidenote- Whenever thinking about recursion, its always easier to think of it like a depth of function calls unfolding and then returning values which then get collected to return the final result.
Anyway, I hope I could clarify myself and hope this gets you started in the right direction.
来源:https://stackoverflow.com/questions/26825084/recursively-remove-all-adjacent-duplicates