leetcode394. 字符串解码

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为:k[encoded_string],表示其中方括号内部的encoded_string正好重复k次。注意k保证为正整数。

你可以认为输入字符串总是有效的;输入字符串没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数k,例如不会出现像3a2[4]的输入。

示例1:
 输入:s = “3[a]2[bc]”
 输出:“aaabcbc”

示例2:
 输入:s = “3[a2[c]]”
 输出:“accaccacc”

思路:
输入的字符串可能存在括号嵌套的情况,此时我们都是先对内部括号中的字符串进行解码,然后再依次对外部括号内的字符串进行解码,也就是说我们从左到右遍历字符串时,先遍历到的[内部的字符串会后进行解码,这符合栈先进后出的特点,因此该问题我们可以借助栈来进行求解。

对输入的字符串进行遍历,遍历时的做法如下:

  • 遍历到的是数字,先将完整的数字字符串提取出来,然后进行压栈。
  • 遍历到的是字母或'[',直接将其进行压栈。
  • 遍历到的是']',先获取到待复制的字符串,再将其进行复制,最好将复制后的字符串重新进行压栈。

当遍历到']'时,具体操作步骤如下:

  1. 先进行弹栈,将弹出的字符串保存到vector当中,直到’[‘被弹出时停止弹栈,’['不保存到vector中。
  2. 再将vector当中的内容进行逆置,因为出栈的顺序与入栈顺序相反。
  3. 然后将待复制的若干字符串进行拼接,得到最终待复制的字符串。
  4. 弹出此时栈顶的数字字符串,并将其转换成整数num。
  5. 将待复制的字符串复制num次,最终得到复制后的字符串。
  6. 将复制后的字符串进行压栈。

最终当输入的字符串遍历完毕时,将栈中的字符串拼接后即为最终解码后的字符串。

动图演示:
在这里插入图片描述
代码如下:

class Solution {
    
    
public:
	//从字符串s的pos位置开始,提取数字字符串
	string GetNum(string& s, size_t& pos)
	{
    
    
		string num;
		while (s[pos] != '[')
		{
    
    
			num += s[pos];
			pos++;
		}
		return num;
	}
	//将vector当中的字符串拼接后进行返回
	string GetString(vector<string>& st)
	{
    
    
		string s;
		for (auto e : st)
		{
    
    
			s += e;
		}
		return s;
	}
	string decodeString(string s) {
    
    
		vector<string> st; //数组模拟栈
		size_t pos = 0; //用于遍历字符串s
		while (pos < s.size())
		{
    
    
			//1、遍历到的是数字,先将完整的数字字符串提取出来,然后进行压栈
			if (isdigit(s[pos]))
			{
    
    
				string num = GetNum(s, pos);
				st.push_back(num);
			}
			//2、遍历到的是字母或'[',直接将其进行压栈
			else if (isalpha(s[pos]) || s[pos] == '[')
			{
    
    
				st.push_back(string(1, s[pos]));
				pos++;
			}
			//3、遍历到的是']',先获取到待复制的字符串,再将其进行复制,最好将复制后的字符串重新进行压栈
			else
			{
    
    
				vector<string> sub; //待复制的若干字符串
				//a、先进行弹栈,将弹出的字符串保存到vector当中,直到'['被弹出时停止弹栈,'['不保存到vector中
				while (st.back() != "[")
				{
    
    
					sub.push_back(st.back());
					st.pop_back();
				}
				st.pop_back();

				//b、再将vector当中的内容进行逆置,因为出栈的顺序与入栈顺序相反
				reverse(sub.begin(), sub.end());

				//c、然后将待复制的若干字符串进行拼接,得到最终待复制的字符串
				string all = GetString(sub);

				//d、弹出此时栈顶的数字字符串,并将其转换成整数num
				int num = stoi(st.back());
				st.pop_back();

				//d、将待复制的字符串复制num次,最终得到复制后的字符串
				string str; //复制后的字符串
				while (num--)
				{
    
    
					str += all;
				}

				//e、将复制后的字符串进行压栈
				st.push_back(str);

				pos++;
			}
		}
		return GetString(st); //将栈当中的字符串拼接后进行返回
	}
};

代码说明:

  • 代码当中并没有使用真正的stack,而是用vector模拟实现的压栈和出栈,是为了方便从栈底向栈顶进行遍历。(这点很重要)
  • GetNum函数的参数pos需要使用引用传参,保证我们一直使用的都是同一个pos变量在对字符串进行遍历。

猜你喜欢

转载自blog.csdn.net/chenlong_cxy/article/details/123239282