【力扣】重新安排行程(很难的回溯题)(未完待续)

题目描述

image

分析

各种意义上都很难 的一道回溯题,首先按照回溯模版写就不是很简单,因为path需要在开头的地方加上JFK,另外,判断字典序优先度如果没有写过的话也很难一下子写出来。就算把这些写出来后,在规模比较大的判例上还是会超时或者超内存。
另外,超时或者超内存不一定是代码性能的问题,也可能是几张票形成了死循环。(但是我的代码里用了used数组,所以应该不会有这个问题)
先贴一下按照模版写出的代码:

using namespace std;
vector<vector<string> > res;
vector<string> path;

vector<string> Prior(vector<vector<string> >& res){
	//找到最优先的结果 
	//cout<<res.size()<<endl;
    vector<string> best = res[0];
    for(int i = 1; i < res.size(); i++){
    	for(int j = 0; j < best.size(); j++){
    		if(best[j] != res[i][j] ){
    			//cout<<i<<" "<<j<<" "<<best[j].compare(res[i][j])<<endl;
    			if(best[j].compare(res[i][j]) > 0){
    				best = res[i];
				}
    			break;
			}
		}
	}
	return best;
}
void backtrace(vector<vector<string> >& tickets, vector<int>& used){
	//cout<<"sizeofpath:"<<path.size()<<" sizeoftickets+1:"<<tickets.size() + 1<<endl;
    if(path.size() == tickets.size()+1){
        res.push_back(path);
        return ;
    }

    for(int i = 0; i < tickets.size(); i++){
        if(used[i] == 1){
            continue;
        }
        if(tickets[i][0] == path.back()){
            path.push_back(tickets[i][1]); 
            //cout<<tickets[i][1]<<endl;
            used[i] = 1;
            backtrace(tickets, used);
            used[i] = 0;
            path.pop_back();
        }
    }
}
    vector<string> findItinerary(vector<vector<string> >& tickets) {
        vector<int> used(tickets.size(), 0);
        res.clear();
        path.push_back("JFK");
        backtrace(tickets, used);
        //cout<<res[0][0]<<endl;
        return Prior(res);
    }
int main(){
	string s1 = "JFK";
	string s2 = "SFO";
	
	//cout<<s1.compare(s2);
	int n;
	cin>>n;
	vector<vector<string> > tickets ;//= {{"MUC","LHR"}, {"JFK","MUC"},{"SFO","SJC"},{"LHR","SFO"}};
	vector<string> tmp;
	string s;
	for(int i = 0; i < n; i++){
		tmp.clear();
		for(int j = 0; j < 2; j++){
			cin>>s;
			tmp.push_back(s);
		}
		tickets.push_back(tmp);
	}
//	for(int i = 0; i < n; i++){
//		for(int j = 0; j < 2;j++){
//			cout<<tickets[i][j]<<" ";
//		}
//		cout<<endl;
//	}
	vector<string> result = findItinerary(tickets);
	for(int i = 0; i < res.size(); i++){
		for(int j = 0; j < res[0].size(); j++){
			cout<<res[i][j]<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
	for(int i = 0; i < result.size(); i++){
		cout<<result[i]<<" ";
	}
	return 0;
}

下面是代码随想录的代码:

class Solution {
private:
// unordered_map<出发机场, map<到达机场, 航班次数>> targets
unordered_map<string, map<string, int>> targets;
bool backtracking(int ticketNum, vector<string>& result) {
    if (result.size() == ticketNum + 1) {
        return true;
    }
    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;
}
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;
    }
};

分析代码:

这个代码里用到了unordered_map这种数据结构,因为数据之间明显存在着映射关系,即每一票一定都对应着另一张票的终点,和某张票的起点。
image
涉及到了哈希表,复试应该不会考到。

posted @ 2024-03-19 22:46  SaTsuki26681534  阅读(1)  评论(0编辑  收藏  举报