https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string/
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
提示:
1 <= S.length <= 20000
S 仅由小写英文字母组成。
小菜鸡独立自主自强的第一遍:
1 class Solution { 2 public: 3 string removeDuplicates(string S) { 4 start: int length = S.length(); 5 for (int i = 0; i < length - 1; i ++) { 6 if (S[i] == S[i + 1]) { 7 S = S.substr(0, i) + S.substr(i + 2, length - i - 2); 8 goto start; 9 } 10 } 11 return S; 12 } 13 };
原理很简单,就是循环遍历字符串,每次当前字符和向后看的一个字符进行比较,如果相同就将前段和后段字符串拼接起来(除去两个相同字符)。通过 goto 语句实现轮回的控制。
(虽然小菜鸡知道使用 goto 不是一个好习惯,但还真不知道这里不用goto要怎么写)(害,菜鸡方式的用时不行啊)
小菜鸡开始看大佬们的题解:
小菜鸡寻思:“这和我写的一样都是 O(N2) 的算法啊(不过这个思路挺巧),但好像 c++ 字符串没有直接可以查找子串的方法啊,那我用js试试!”
(也学习了不使用 goto 的方法 (因为 js 没有 goto 啊!))
1 var removeDuplicates = function(S) { 2 var list = ["aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo", "pp", "qq", "rr", "ss", "tt", "uu", "vv", "ww", "xx", "yy", "zz"]; 3 prev_length = -1; 4 while (prev_length != S.length) { 5 prev_length = S.length; 6 var length = list.length; 7 for (var i = 0; i < length; i ++) { 8 var po = S.indexOf(list[i]); 9 if (po != -1) { 10 S = S.substr(0, po) + S.substr(po + 2, length - po - 2); 11 } 12 } 13 } 14 return S; 15 };
小菜鸡继续看大佬们的题解:
1 class Solution { 2 public: 3 string removeDuplicates(string S) { 4 stack<char> result; 5 int length = S.length(); 6 result.push(S[0]); 7 for (int i = 1; i < length; i ++) { 8 if (result.empty() || S[i] != result.top()) { 9 result.push(S[i]); 10 } else { 11 result.pop(); 12 continue; 13 } 14 } 15 string re; 16 int size = result.size(); 17 for(int i = 0; i < size; i ++) { 18 re = result.top() + re; 19 result.pop(); 20 } 21 return re; 22 } 23 };
他是一个优秀的O(N)算法!!!
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。