这是一个正确的解决方案
是的。考虑到@rici 提到的内容,让我尝试清理您使用堆栈的想法。
你想遍历字符串一次的字符。这就是您的算法流程:
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.
上面的算法显然是O(N),因为在每一步 3,我们肯定会从 Stack A 中弹出一个元素,因此 Stack A 的大小在每一步 3 之后都会减少 1。
谁能解释一下帖子中解释的o(n)解决方案?
来到您想挂断的recursive algorithm。事情是这样的:
函数removeUtil在任何时间点都有两个值——一个是字符数组str
我们必须从中删除相邻的重复项,另一个是字符last_removed。
带有一些描述的伪代码 -
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;
由于我们正在遍历字符数组并“形成”通过适当附加和删除字符返回的最终字符数组,因此时间复杂度为 O(N)。
旁注- 每当考虑递归时,总是更容易将其想象为函数调用的深度展开,然后返回值,然后收集这些值以返回最终结果。
无论如何,我希望我能澄清自己,并希望这能让你朝着正确的方向开始。