1.括号生成
其实不考虑减枝,下面代码就是将所有开头第一个括号为“(”的结果一并写出了
s+='('; _generateParenthesisR(ret,s,left+1,right,n); s.pop_back(); s+=')'; _generateParenthesisR(ret,s,left,right+1,n); s.pop_back();
那么此外我们就要进行减枝和收获的判断
1.首先明确每一个参数是干什么的:
vector<string>& ret存放收获的返回结果
string& s存每次递归的结果
int left,int right,分别用于记录左右括号的出现次数
int& n,为题目给出的几组括号
2.那么我们的判断条件其实很简单:要清楚我们是先考虑左括号的
那么条件就有以下三种:收获的情况 / 不可出现的情况 / 左括号满的情况
left==n&&right==n:此时都是成双成对,那么我们收获即可
left<right:结果右括号的数大于左括号的数,那么这个结果是错误的,直接返回给上层
eft==n&&right<n:左括号满了,那么此时只能操作右括号
class Solution {
public:
void _generateParenthesisR(vector<string>& ret,string& s,int left,int right,int& n)
{
if(left==n&&right==n)
{
ret.push_back(s);
return;
}
else if(left<right)
{
return;
}
else if(left==n&&right<n)
{
s+=')';
_generateParenthesisR(ret,s,left,right+1,n);
s.pop_back();
return;
}
s+='(';
_generateParenthesisR(ret,s,left+1,right,n);
s.pop_back();
s+=')';
_generateParenthesisR(ret,s,left,right+1,n);
s.pop_back();
}
vector<string> generateParenthesis(int n) {
vector<string> ret;
string s;
_generateParenthesisR(ret,s,0,0,n);
return ret;
}
};
2.重新安排行程
本题最难的地方有两处:1.怎么表示各点关系 2.怎么用代码遍历
其实思路和之前的回溯都差不多,最难的点搞定后无非就是回溯暴力求解
1.怎么表示各点关系:使用unordered_map<string, map<string, int>> targets定义,第一个string为以该点出发的飞机场名;map的string是表示能去往哪里的飞机场名;map的int是标明在递归时,我们是否已经去过这条路了。
2.介绍函数的参数
ret:返回结果的容器
targets:所有飞机场路线的图,需要遍历的到;思路就是遍历tickets,对应的左边是第一个string,右边是第二个string,我们要做的就是将第二个string的int类型记录加一,表示左边的飞机场到右边的飞机场有一个路径,全部遍历。
for (auto& e : tickets) targets[e[0]][e[1]]++;
num:当前层的飞机已走路径数量
3.
* 遍历条件其实很简单了,我们只需要找到唯一的那条最长路(起点加上所有路径之和的数量就是我们所想要的最后终止条件),所以我们的函数返回值为bool,只需要返回最终结果即可,最终为ret.size() == num
* 那么auto& e : targets[ret[ret.size() - 1]]找到当前飞机场能走向的其他飞机场情况,如果有则second--,ret要push当前的飞机场,随后进行回溯。如果回溯的结果成功,说明其他结果没必要,直接向上返回true。那回溯的思路就是ret先pop最后的飞机场,secong重新++回来
class Solution {
public:
bool backtrace(vector<string>& ret, unordered_map<string, map<string, int>>& targets, int& num)
{
if (ret.size() == num)
return true;
//写法一
/*for(auto& it:targets)
{
cout<<it.first<<" "<<ret[ret.size() - 1]<<endl;
if(it.first==ret[ret.size() - 1])
{
for(auto& e: it.second)
{
if (e.second > 0)
{
ret.push_back(e.first);
e.second--;
if (backtrace(ret, targets, num))
return true;
ret.pop_back();
e.second++;
}
}
}
}*/
//写法二
for (auto& e : targets[ret[ret.size() - 1]])
{
if (e.second > 0)
{
ret.push_back(e.first);
e.second--;
if (backtrace(ret, targets, num))
return true;
ret.pop_back();
e.second++;
}
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> ret;
unordered_map<string, map<string, int>> targets;
targets.clear();
for (auto& e : tickets)
targets[e[0]][e[1]]++;
ret.push_back("JFK");
int num = tickets.size() + 1;
backtrace(ret, targets, num);
return ret;
}
};