LeetCode 394. Decode String
题目链接:https://leetcode.com/problems/decode-string/
题目描述:
The encoding rule is: k[encoded_string]
, where the encoded_string inside the square brackets is being repeated exactly k times. Note thatk is guaranteed to be a positive integer.
You may assume that the input string is always valid; 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 won't be input like 3a
or2[4]
.
Examples:
s = "3[a]2[bc]", return "aaabcbc". s = "3[a2[c]]", return "accaccacc". s = "2[abc]3[cd]ef", return "abcabccdcdcdef".思路1:一开始自己想的,不会设计递归,用的循环,每次记录最后一次出现的'[',和第一次出现的‘]’,将这之间的子串重复,并插入']'的前面,再从开头搜索,一直到都解码。这种方法时间复杂度肯定高一些,但是从运行时间来看没有比下面两种方法慢。只想着记录方括号的位置,所以只想到这个方法。
代码:
class Solution {
public:
string decodeString(string s) {
while(s.find_last_of('[',s.size()-1)!=-1)
{
int left=s.find_last_of('[',s.size()-1);//找到最后一个出现的'['
int right=s.find_first_of(']',left+1);//在最后一个出现的'['的后面找‘]’
int p=left;
string numstr="";
int count=0;
//times可能不止1位数,把数字找全
while(p-1>=0&&s[p-1]>47&&s[p-1]<58)
{
numstr.insert(0,to_string(s[p-1]-'0'));
count++;
p--;
}
int times;
stringstream stream;
stream<<numstr;
stream>>times;
string tmp=s.substr(left+1,right-left-1);//提取子串
int subLen=tmp.size();
//把times-1个子串插入到‘]’前面
for(int i=0;i<times-1;i++)
{
s.insert(right,tmp);
right+=subLen;
}
//去掉这一层的'[',']',数字
s=s.replace(right,1,"");
s=s.replace(left,1,"");
s=s.replace(left-count,count,"");
}
return s;
}
};
思路2:用递归,自己老是设计不好递归,借鉴网上的思路。递归函数里面用一个while循环,循环终止条件是遇到‘]’,返回
class Solution {
public:
string decodeString(string s) {
int i = 0;
return decoding(s, i);
}
//递归函数
string decoding(string s, int &i){
string res = "";//结果字符串
while (i<s.size() && s[i] != ']'){//循环终止的条件,遇到结尾或者']'
if (s[i] >= 'a'&&s[i] <= 'z')//遇到的是字母,直接添加到结果字符串中
res += s[i++];
else{//先遇到的不是字母就一定是数字
int cnt = 0;
while (i<s.size()&&s[i]>='0'&&s[i]<='9'){
cnt = 10 * cnt + s[i++] - '0';
}
i++;//从'['的后面一位开始进入递归函数
string t = decoding(s, i);//返回已经待解码的的子串
i++;
while (cnt--){//将子串解码与前面的部分结合起来
res += t;
}
}
}
return res;
}
};
思路3:借助栈stack,用循环。用两个栈,一个存储重复次数,一个存储字母
代码:
class Solution {
public:
string decodeString(string s) {
string res = "", t = "";
stack<int> s_num;
stack<string> s_str;
int cnt = 0;
for (int i = 0; i < s.size(); ++i) {
if (s[i] >= '0' && s[i] <= '9') {
cnt = 10 * cnt + s[i] - '0';
} else if (s[i] == '[') {
s_num.push(cnt);
s_str.push(t);
cnt = 0; t.clear();
} else if (s[i] == ']') {
int k = s_num.top(); s_num.pop();
for (int j = 0; j < k; ++j) s_str.top() += t;
t = s_str.top(); s_str.pop();
} else {
t += s[i];
}
}
return s_str.empty() ? t : s_str.top();
}
};
参考链接: http://www.cnblogs.com/grandyang/p/5849037.html
总结:虽然写出来了,但是没有用主流的方法,递归的实用还是弱项,需要加强练习
LeetCode 385. Mini Parser
题目链接:https://leetcode.com/problems/mini-parser/
题目描述:
Given a nested list of integers represented as a string, implement a parser to deserialize it.
Each element is either an integer, or a list -- whose elements may also be integers or other lists.
Note: You may assume that the string is well-formed:
- String is non-empty.
- String does not contain white spaces.
- String contains only digits
0-9
,[
,-
,
,]
.
Example 1:
Given s = "324", You should return a NestedInteger object which contains a single integer 324.
Example 2:
Given s = "[123,[456,[789]]]", Return a NestedInteger object containing a nested list with 2 elements: 1. An integer containing value 123. 2. A nested list containing two elements: i. An integer containing value 456. ii. A nested list with one element: a. An integer containing value 789.思路:这个题看不懂题意,,,百度了才明白,自己定义的那个类没明白是干什么的,,,但看着答案跟上面一题相像,就暂时先放到这里来吧,总结一点:遇到这种一层层括号的考虑用栈+循环或者递归
/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* class NestedInteger {
* public:
* // Constructor initializes an empty nested list.
* NestedInteger();
*
* // Constructor initializes a single integer.
* NestedInteger(int value);
*
* // Return true if this NestedInteger holds a single integer, rather than a nested list.
* bool isInteger() const;
*
* // Return the single integer that this NestedInteger holds, if it holds a single integer
* // The result is undefined if this NestedInteger holds a nested list
* int getInteger() const;
*
* // Set this NestedInteger to hold a single integer.
* void setInteger(int value);
*
* // Set this NestedInteger to hold a nested list and adds a nested integer to it.
* void add(const NestedInteger &ni);
*
* // Return the nested list that this NestedInteger holds, if it holds a nested list
* // The result is undefined if this NestedInteger holds a single integer
* const vector<NestedInteger> &getList() const;
* };
*/
class Solution {
public:
NestedInteger deserialize(string s) {
if(s[0] != '[') return NestedInteger(stoi(s));
stack<NestedInteger*> stk;
NestedInteger* ret = NULL;
int idx = 0;
for(int i=0; i<s.size(); ++i) {
if(s[i] == '[') {
stk.push(new NestedInteger());
if(!ret) ret = stk.top();
idx = i + 1;
}
else if(s[i] == ']' || s[i] == ',') {
if(idx != i)
stk.top()->add(NestedInteger(stoi(s.substr(idx, i-idx))));
if(s[i] == ']') {
NestedInteger* cur = stk.top();
stk.pop();
if(!stk.empty()) stk.top()->add(*cur);
}
idx = i + 1;
}
}
return *ret;
}
};