回溯算法-重新安排行程

leetcode332.重新安排行程
这题我还没自己ac过,只能现在凭着刚学完的热乎劲把我对题解的理解记下来。
本题我认为对数据结构的考察比较多,用什么数据结构去存数据,去读取数据,都是很重要的。

class Solution {
private:
    unordered_map<string,map<string,int>> targets;
    bool backtracking(int ticketNum,vector<string>& result){//1.确定参数和返回值
    	//2.确定递归的结束
        if(result.size()==ticketNum+1){
            return true;
        }
        //3.确定单层递归的逻辑
        for(pair<const string,int>& target:targets[result[result.size()-1]]){
            
            if(target.second>0){//处理节点
                result.push_back(target.first);
                target.second--;
                if(backtracking(ticketNum,result)) return true;//递归
                result.pop_back();//回溯
                target.second++;
            }
        }
        return false;//如果前面一直没返回true,这里就直接返回false
        
    }    
public:
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        targets.clear();
        vector<string> result;
        for(const vector<string>& vec:tickets){
        //
            targets[vec[0]][vec[1]]++;
        }
        result.push_back("JFK");
        backtracking(tickets.size(),result);
        return result;
    }
};
  1. 返回true的原因:
    如果到达最底层叶子结点的时候依旧是返回true,这样一层一层返回到最顶层,这也是为什么for循环里面if(backtracking(ticketNum,result)) return true;就是当判断下面那层返回true的时候,本层才会返回true,这样一层一层返回。
  2. 判断递归结束的条件if(result.size()==ticketNum+1),题目要求每张票都必须用到且只能用一次。我们知道4张票代表有5个机场,result里面放的是机场名称,因此要+1。
  3. pair& target:targets[result[result.size()-1] ]
    这里我画一张图,可以更好的理解result,pair类型的target,targets这些数据结构
    回溯算法-重新安排行程_第1张图片
    回溯算法-重新安排行程_第2张图片
    描述的已经很详细了,pair类型的tartget的tartget.first和target.second各自的含义就不在多叙述了
  4. targets[vec[0]][vec[1]]++中vec指从题目给的tickets数组中取出的一个个容器,每个vec包含两个元素,即出发点和目的地,那么targets[vec[0]][vec[1]]++中第一个vec[0]是指作为key找到unordered_map里对应的map,vec[1]指作为key找到map里面对应的int即票数,给对应的票数+1,这样层层印射,最终找到了,从出发点到目的地对应的票数,这个主函数里面的for循环就是为了初始化targets数组
  5. 最后常规的回溯三部曲,理解每一树层目的是什么,每次递归的目的是什么,最后结果是怎样收集的。

你可能感兴趣的:(算法,数据结构,图论,c++,图搜索)