拓扑排序
找到做事情的先后顺序,拓扑排序的结果可能不是唯一的
如何排序?
- 找出图中入度为 0 的点,然后输出
- 删除与该点连接的边
- 重复 1、2 操作,直到图中没有点或者没有入度为 0 的点为止
实现拓扑排序
借助队列,来一次 BFS 即可
- 初始化:把所有入度为 0 的点加入到队列中
- 当队列不为空的时候:拿出队头元素,加入到最终结果中;删除与该元素相连的边;判断:与删除边相连的点,是否入度变成 0 如果入度为 0,加入到队列中
借助STL容器灵活建图
vector<vector> edges;
unordered_map<int,vector> edges;
根据算法流程,灵活建图
每个顶点的入度 vector in;
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
- 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class Solution { public: bool canFinish(int numCourses, vector<vector<int>>& prerequisites) { unordered_map<int,vector<int>> edges; vector<int> in(numCourses);
for(auto e:prerequisites){ int a=e[0],b=e[1]; edges[b].push_back(a); in[a]++; }
a queue<int> q; for(int i=0;i<numCourses;i++){ if(in[i]==0){ q.push(i); } }
while(!q.empty()){ int t=q.front();q.pop();
for(int a:edges[t]){ in[a]--; if(in[a]==0){ q.push(a); } } }
for(int i=0;i<numCourses;i++){ if(in[i]) return false; } return true; } };
|
描述
体育课共有 numProject个考核项目,编号为 0到 numProject−1,考核中每两个项目被划分为一组得到分组数组
groupsi ,现规定若想完成项目 groupsi[0],必须先完成 groupsi[1]。保证所有分组互不相同,
若分组情况能顺利完成考核,请返回任意的一个完成顺序,否则返回空数组 。
数据范围:
1≤numProject≤2000 1≤groupsi.length≤numProject∗(numProject−1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include <queue> #include <unordered_map> class Solution { public: vector<int> findOrder(int numProject, vector<vector<int> >& groups) { unordered_map<int, vector<int>> edges; vector<int> in(numProject,0); vector<int> ans;
for(auto e:groups){ int a=e[0],b=e[1]; edges[b].push_back(a); in[a]++; }
queue<int> q; for(int i=0;i<numProject;i++){ if(in[i]==0){ q.push(i); } }
while(!q.empty()){ int t=q.front();q.pop(); ans.push_back(t); for(int a:edges[t]){ in[a]--; if(in[a]==0){ q.push(a); } } }
if(ans.size()!=numProject){ return {}; } return ans; } };
|
快速排序
给你一个整数数组 nums,请你将该数组升序排列。
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Solution { public: vector<int> sortArray(vector<int>& nums) { srand(time(NULL)); qsort(nums,0,nums.size()-1); return nums; }
void qsort(vector<int>& nums,int left,int right) { if(left>=right) return; int key=get_rand(nums,left,right); int i=left,l=left-1,r=right+1; while(i<r) { if(nums[i]<key) swap(nums[++l],nums[i++]); else if(key==nums[i]) i++; else swap(nums[i],nums[--r]); }
qsort(nums,left,l); qsort(nums,r,right); }
int get_rand(vector<int>& nums,int left,int right) { int r=rand(); return nums[r%(right-left+1)+left]; } };
|
归并排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Solution { vector<int> ret; public: vector<int> sortArray(vector<int>& nums) { ret.resize(nums.size()); Mergesort(nums,0,nums.size()-1); return nums; }
void Mergesort(vector<int>& nums,int left,int right) { if(left>=right) return; int mid=(left+right)>>1;
Mergesort(nums,left,mid); Mergesort(nums,mid+1,right);
int cur1=left,cur2=mid+1,i=0; while(cur1<=mid&&cur2<=right) { ret[i++]=nums[cur1]<nums[cur2]?nums[cur1++]:nums[cur2++]; } while(cur1<=mid) ret[i++]=nums[cur1++]; while(cur2<=right) ret[i++]=nums[cur2++];
for(i=left;i<=right;i++) nums[i]=ret[i-left]; } };
|