LeetCode 394. -Decode String
Medium
Given an encoded string, return its decoded string.
The encoding rule is: k[encoded_string]
, where the encoded_string
inside the square brackets is being repeated exactly k
times. Note that k
is guaranteed to be a positive integer.
You may assume that the input string is always valid; there are no extra white spaces, square brackets are well-formed, etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k
. For example, there will not be input like 3a
or 2[4]
.
The test cases are generated so that the length of the output will never exceed 105
.
Example 1:
Input: s = "3[a]2[bc]"
Output: "aaabcbc"
Example 2:
Input: s = "3[a2[c]]"
Output: "accaccacc"
Example 3:
Input: s = "2[abc]3[cd]ef"
Output: "abcabccdcdcdef"
Constraints:
1 <= s.length <= 30
s
consists of lowercase English letters, digits, and square brackets'[]'
.s
is guaranteed to be a valid input.All the integers in
s
are in the range[1, 300]
.
Solution
Algorithm
create a stack
add the string in reverse order to the stack so that we can get the left elements on top
pop the stack and build a string till you find a digit
find the length of the digit by looping till you find the whole number with all the digits
till you find matching braces, pop elements and store them
use the stored elements to loop through and push them to the stack
repeat till the string contains no encoding strings
return the value
Use Character.isDigit(n)
to get the boolean value
Integer.parseInt(String.valueOf(n))
to find the value of the digit
or num = num * 10 + c - '0';
Edge cases
If the digit is more than 9 (two digits or more) - you need to pop till you find the entire element
braces - loop till yoiu find a matching brace and brace left and brace right are equal
class Solution {
public String decodeString(String s) {
// the major loop is to decode each sub string and push it to the stack
// edge cases are - if the number value has more than one decimal point
Stack<Character> stk = new Stack<>();
StringBuilder cs = new StringBuilder();
//push the values in reverse order on the stack so that we can get the first element on top of the stack
for(int i = s.length() - 1; i>=0; i--){
stk.push(s.charAt(i));
}
while(!stk.isEmpty()){
// get the current character and remove it from stack
char v = stk.pop();
int num;
if(Character.isDigit(v)) {
// string builder for loops instead of a string for memory efficency
StringBuilder kk = new StringBuilder();
kk.append(v);
// if the value is a digit more than one decimal point, concat the values
while(Character.isDigit(stk.peek())){
kk.append(stk.pop());
}
// parse the concated number
num = Integer.parseInt(kk.toString());
ArrayList<Character> ls = new ArrayList<>();
// remove the first brace
stk.pop();
int braces = 1;
// we add it to the list till we find a matching brace
while(braces > 0){
char m = stk.pop();
if(m == '[') braces++;
if(m == ']') braces --;
ls.add(m);
}
for(int w = 0; w < num; w++) {
// the minus 2 is to remove the brace we added in the wile loop while looking for enclosing braces
for(int j = ls.size() - 2; j>=0; j--){
// add the enclosed values inside braces k times
stk.push(ls.get(j));
}
}
}
else {
// otherwise the value is a string so append it
cs.append(v);
}
}
return cs.toString();
}
}
Last updated