【每日刷题】Day157

【每日刷题】Day157

🥕个人主页:开敲🍉

🔥所属专栏:每日刷题🍍

🌼文章目录🌼

[1. 207. 课程表 - 力扣(LeetCode)](#1. 207. 课程表 - 力扣(LeetCode))

[2. LCR 113. 课程表Ⅱ - 力扣(LeetCode)](#2. LCR 113. 课程表Ⅱ - 力扣(LeetCode))

[3. LCR 114. 火星词典 - 力扣(LeetCode)](#3. LCR 114. 火星词典 - 力扣(LeetCode))

1. 207. 课程表 - 力扣(LeetCode)

//思路:BFS+拓扑排序

//拓扑排序:针对有向无环图的排序算法。

//BFS实现拓扑排序:将有向无环图中所有 入度 为0的点入队列,随后向外扩展,每次取出队列头部点,并将连接该点的边删去,并将与该点相连的点的入度--:

//当最后图中没有任何点 || 没有任何入度为 0 的点时,说明可以将所有课程学完,返回true;否则,返回 false

class Solution {

public:

bool canFinish(int n, vector<vector<int>>& p)

{

unordered_map<int,vector<int>> hash;

vector<int> edges(n);//记录每个点的入度

for(auto& e : p)//建图

{

int a = e0,b = e1;

hashb.push_back(a);

edgesa++;

}

queue<int> qu;

for(int i = 0;i<n;i++)//将所有入度为 0 的点入队列

if(!edgesi) qu.push(i);

while(!qu.empty())

{

int tmp = qu.front();

qu.pop();

for(int i = 0;i<hashtmp.size();i++)

if(!(--edgeshash\[tmpi])) qu.push(hashtmpi);//每次取出队列头部点,并将连接该点的边删去,并将与该点相连的点的入度--,如果元素的入度减为 0 ,则继续入队列

}

for(int i = 0;i<n;i++)

if(edgesi) return false;//如果最后图中还有点,则返回 false

return true;

}

};

2. LCR 113. 课程表Ⅱ - 力扣(LeetCode)

//思路:BFS+拓扑排序。

//思路与上一题 "课程表" 完全一样,代码也几乎一模一样,只需要将每次入度为 0 的点放入一个结果数组中即可。

class Solution {

public:

vector<int> findOrder(int n, vector<vector<int>>& p)

{

vector<int> ans;

vector<int> tmp;

unordered_map<int,vector<int>> hash;

vector<int> edges(n);

for(auto& e : p)//建图

{

int a = e0,b = e1;

hashb.push_back(a);

edgesa++;

}

queue<int> qu;

for(int i = 0;i<n;i++)//将所有入度为 0 的点放入队列和结果数组中。

{

if(!edgesi)

{

qu.push(i);

ans.push_back(i);

}

}

while(!qu.empty())

{

int tmp = qu.front();

qu.pop();

for(int i = 0;i<hashtmp.size();i++)//每次取出队列头部点,并将连接该点的边删去,并将与该点相连的点的入度--,如果元素的入度减为 0 ,则继续入队列,并且将其放入结果数组中。

{

if(!(--edgeshash\[tmpi]))

{

qu.push(hashtmpi);

ans.push_back(hashtmpi);

}

}

}

for(int i = 0;i<n;i++)//如果无法完成所有课程,则返回空数组

if(edgesi) return tmp;

return ans;

}

};

3. LCR 114. 火星词典 - 力扣(LeetCode)

//思路:BFS+拓扑排序+哈希

//本题的难点在于:如何记录字符的边以及入度个数?

//这里是用哈希表的方式解决的:

① 记录边:使用哈希嵌套哈希的方式,对于每个字符出去的边,记录在一个 unordered_set中,这样可以避免重复记录,如 "wrt" "er" "ett",如果不使用哈希表记录会重复记录 w -> e这条边

② 记录入度个数:使用哈希表,对于每个 char,记录有多少个入度。使用时必须先初始化------ 将 words 中出现的所有字符的入度初始化为 0

class Solution

{

unordered_map<char,unordered_set<char>> edges;//记录边

unordered_map<char,int> in;//记录入度个数

bool check = false;//这个用于处理特殊情况:"abc" "ab",这种情况下是不合法的,但是我们的拓扑排序没法解决

public:

void add(string& s1,string& s2)//建图

{

int sub = 0;

while(sub<min(s1.size(),s2.size()))

{

int a = s1sub,b = s2sub;

if(a!=b) //遇到不同字符时记录

{

if(!edgesa.count(b))//建边前判断一下是否已经存在了这条边,防止重复记录,如上面的 w -> e

{

edgesa.insert(b);//建边

inb++;//记录入度个数

}

return;

}

sub++;

}

if(s1.size()>s2.size())//当前 min(s1.size(),s2.size())个字符都相同时就会跳出上面循环来到这,如果前一个字符串的长度 > 后一个字符串的长度,则不合法,将 check 置为 true

check = true;

}

string alienOrder(vector<string>& words)

{

string ans;

int n = words.size();

for(auto& s : words)

for(auto c : s)

inc = 0;

for(int i = 0;i<n;i++)

{

for(int j = i+1;j<n;j++)

{

add(wordsi,wordsj);//两层 for 循环建图

if(check) return "";//当 check 为 true时,返回空串

}

}

queue<char> qu;

for(auto& a,b : in)//将所有入度为 0 的字符入队列

if(!b) qu.push(a);

while(!qu.empty())//BFS

{

char tmp = qu.front();

qu.pop();

ans+=tmp;

for(char c : edgestmp)

if(!(--inc)) qu.push(c);//每次取出队列头部点,并将连接该点的边删去,并将与该点相连的点的入度--,如果元素的入度减为 0 ,则继续入队列,并且将其放入结果数组中。

}

for(auto& a,b : in)//最后判断图中是否还存在点

if(b) return "";

return ans;

}

相关推荐
kkeeper~3 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs6664 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964135 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚5 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本5 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Ulyanov7 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫7 小时前
特征工程处理
人工智能·算法·机器学习
z落落7 小时前
C#参数区别
java·算法·c#
c238568 小时前
vector(下)
数据结构·算法
z落落8 小时前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法