(leetcode)1601.最多可达成的换楼请求
考察了dfs+回溯
开始还以后在出度、入度这里做文章,看来是想的太简单了,思考了1小时后果断放弃,困难题果然不是我等凡夫俗子10分钟就能想出来的,这是看了官方题解,在自己理解的基础上敲了一遍
class Solution { private: //delta[i]代表第i楼员工变化量 vector<int> delta; //cnt代表被选择的请求数量;ans是最大请求数 //zero代表0的数目,维护zero是为了判断当前所有楼是否净变化量为0 int ans=0,cnt=0,zero,n; public: void dfs(vector<vector<int>> &requests,int pos){ if(pos==requests.size()){ //枚举到最后一个请求 if(zero==n){ ans=max(ans,cnt); } return; } //不选request[pos] dfs(requests,pos+1); int z=zero; ++cnt; //引用变量,r改变,requests中对应元素也会改变 auto &r=requests[pos]; //x是起点,y是终点 int x=r[0],y=r[1]; //因为x出去了,所以0的数量少1 zero-=delta[x]==0; //x出去一个人 --delta[x]; //若出去后x=0,则zero再加上1 zero+=delta[x]==0; //若y本身为0,则进入1个人后会加1,则整体的0少1个 zero-=delta[y]==0; //y进入一个人 ++delta[y]; //若delta[y]加上1后变为0,则整体0多1个 zero+=delta[y]==0; //深搜接受该请求后的情况 dfs(requests,pos+1); //回溯 --delta[y]; ++delta[x]; --cnt; zero=z; } int maximumRequests(int n, vector<vector<int>>& requests) { delta.resize(n); zero=n; this->n=n; dfs(requests,0); return ans; } };
再补充一个递归、回溯的区别(转自https://blog.csdn.net/fengchi863/article/details/80086915?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.pc_relevant_paycolumn_v3&spm=1001.2101.3001.4242.1&utm_relevant_index=3
递归是一种算法结构、回溯是一种算法思想
前者是自己调用自己解决问题
后者是通过不同的尝试生成问题的解,类似于穷举,但回溯和穷举不同之处是回溯会剪枝,剪枝就是回溯在执行过程中对已经不可能达到目标的结果不会继续执行下去,即不保留完整的树结构,而深搜保留完整的树结构