Skip to content

Commit aa6c474

Browse files
committed
Implement decode-string
name: decode-string url: https://leetcode.com/problems/decode-string difficulty: 2 time: 0 ms time-rank: 100 % time-complexity: O(N) space: 6.5 MB space-rank: 100 % space-complexity: O(N) Fixes #292 Signed-off-by: Christopher Friedt <[email protected]>
1 parent 6bc9768 commit aa6c474

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

decode-string-test.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2021, Christopher Friedt
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#include <gtest/gtest.h>
8+
9+
#include "decode-string.cpp"
10+
11+
using namespace std;
12+
13+
TEST(DecodeString, 3_a_2_bc_) {
14+
EXPECT_EQ("aaabcbc", Solution().decodeString("3[a]2[bc]"));
15+
}
16+
17+
TEST(DecodeString, 3_a2_c__) {
18+
EXPECT_EQ("accaccacc", Solution().decodeString("3[a2[c]]"));
19+
}
20+
21+
TEST(DecodeString, 2_abc_3_cd_ef) {
22+
EXPECT_EQ("abcabccdcdcdef", Solution().decodeString("2[abc]3[cd]ef"));
23+
}
24+
25+
TEST(DecodeString, abc3_cd_xyz) {
26+
EXPECT_EQ("abccdcdcdxyz", Solution().decodeString("abc3[cd]xyz"));
27+
}

decode-string.cpp

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2021, Christopher Friedt
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
// clang-format off
8+
// name: decode-string
9+
// url: https://leetcode.com/problems/decode-string
10+
// difficulty: 2
11+
// clang-format on
12+
13+
#include <vector>
14+
15+
using namespace std;
16+
17+
class Solution {
18+
public:
19+
string decodeString(string s) {
20+
// maintain stacks (lifo queues) for both lefts and rights
21+
// it takes O(N) time to go through s and populate them
22+
23+
// possible optimization:
24+
// technically speaking, there can be maximally N/4 lefts and N/4 rights
25+
// so maybe it just makes sense to preallocate that amount and keep
26+
// an L and R handy.
27+
// the question says that s will be maximally 30 characters.
28+
// so that would allow us to be O(1) space (except for the output
29+
// which is proportional in length to the input, so O(N)).
30+
31+
stringstream ss;
32+
vector<size_t> nums;
33+
uint8_t lefts = 0;
34+
vector<string> strs;
35+
string num;
36+
bool have_number = false;
37+
38+
for (size_t i = 0, N = s.size(); i < N; ++i) {
39+
if ('[' == s[i]) {
40+
// we can now parse the number string that precedes the '[' character
41+
nums.push_back(stoi(num));
42+
num.clear();
43+
++lefts;
44+
strs.push_back("");
45+
46+
} else if (']' == s[i]) {
47+
48+
auto j = nums.back();
49+
string t = strs.back();
50+
51+
nums.pop_back();
52+
lefts--;
53+
strs.pop_back();
54+
55+
if (nums.size() > 0) {
56+
for (; j > 0; --j) {
57+
strs.back() += t;
58+
}
59+
} else {
60+
for (; j > 0; --j) {
61+
ss << t;
62+
}
63+
}
64+
65+
} else if ('0' <= s[i] && s[i] <= '9') {
66+
have_number = true;
67+
num.push_back(s[i]);
68+
} else if ('a' <= s[i] && s[i] <= 'z') {
69+
if (!have_number || lefts == 0) {
70+
ss << s[i];
71+
} else {
72+
strs.back().push_back(s[i]);
73+
}
74+
}
75+
}
76+
77+
return ss.str();
78+
}
79+
};

0 commit comments

Comments
 (0)