【优选算法】(第四十六篇)

news2024/10/20 21:02:01

目录

课程表II(medium)

题目解析

讲解算法原理

编写代码

⽕星词典(hard)

题目解析

讲解算法原理

编写代码


课程表II(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

现在你总共有 numCourses ⻔课需要选,记为 0 到 numCourses - 1 。给你⼀个数组
prerequisites ,其中 prerequisites[i] = [a(i), b(i)] ,表⽰在选修课程a(i) 前必须先选修 b(i) 。
• 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们⽤⼀个匹配来表⽰: [0,1] 。返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回任意⼀种就可
以了。如果不可能完成所有课程,返回⼀个空数组。

⽰例1:
输⼊:numCourses=2,prerequisites=[[1,0]]
输出:[0,1]
解释:总共有2⻔课程。要学习课程1,你需要先完成课程0。因此,正确的课程顺序为[0,1]。⽰例2:
输⼊:numCourses=4,prerequisites=[[1,0],[2,0],[3,1],[3,2]]
输出:[0,2,1,3]
解释:总共有4⻔课程。要学习课程3,你应该先完成课程1和课程2。并且课程1和课程2都应该排在课程0之后。[0,1,2,3]。另⼀个正确的排序是[0,2,1,3]。
⽰例3:
输⼊:numCourses=1,prerequisites=[]
输出:[0]

提⽰:
◦ 1 <= numCourses <= 2000
◦ 0 <= prerequisites.length <= numCourses * (numCourses - 1)
◦ prerequisites[i].length == 2
◦ 0 <= a(i), b(i) < numCourses
◦ a(i) != b(i)
◦ 所有 [a(i), b(i)] 互不相同

讲解算法原理

解法:
算法思路:

和上⼀题⼀样~

编写代码

c++算法代码:

class Solution
{
public:
 vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) 
 {
 // 1. 准备⼯作
 vector<vector<int>> edges(numCourses); // 邻接表存储图
 vector<int> in(numCourses); // 存储每⼀个点的⼊度
 // 2. 建图
 for(auto& p : prerequisites)
 {
 int a = p[0], b = p[1]; // b -> a
 edges[b].push_back(a);
 in[a]++;
 }
 // 3. 拓扑排序
 vector<int> ret; // 统计排序后的结果
 queue<int> q;
 for(int i = 0; i < numCourses; i++)
 {
 if(in[i] == 0) q.push(i);
 }
 while(q.size())
 {
 int t = q.front(); q.pop();
 ret.push_back(t);
 for(int a : edges[t])
 {
 in[a]--;
 if(in[a] == 0) q.push(a);
 }
 }
 if(ret.size() == numCourses) return ret;
 else return {};
 }
};

java算法代码:

class Solution
{
 public int[] findOrder(int n, int[][] prerequisites) 
 {
 // 1. 准备⼯作
 int[] in = new int[n]; // 统计每个顶点的⼊度
 List<List<Integer>> edges = new ArrayList<>();
 for(int i = 0; i < n; i++)
 {
 edges.add(new ArrayList<>());
 }
 // 2. 建图
 for(int i = 0; i < prerequisites.length; i++)
 {
 int a = prerequisites[i][0], b = prerequisites[i][1]; // b -> a
 edges.get(b).add(a);
 in[a]++;
 }
 // 3. 拓扑排序
 Queue<Integer> q = new LinkedList<>();
 int[] ret = new int[n];
 int index = 0;
 for(int i = 0; i < n; i++)
 {
 if(in[i] == 0) q.add(i);
 }
 while(!q.isEmpty())
 {
 int t = q.poll();
 ret[index++] = t;
 for(int a : edges.get(t))
 {
 in[a]--;
 if(in[a] == 0) q.add(a);
 }
 }
 if(index == n) return ret;
 return new int[0];
 }
}

⽕星词典(hard)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

现有⼀种使⽤英语字⺟的外星⽂语⾔,这⻔语⾔的字⺟顺序与英语顺序不同。
给定⼀个字符串列表 words ,作为这⻔语⾔的词典, words 中的字符串已经按这⻔新语⾔的字⺟顺序进⾏了排序。
请你根据该词典还原出此语⾔中已知的字⺟顺序,并按字⺟递增顺序排列。若不存在合法字⺟顺序,返回 "" 。若存在多种可能的合法字⺟顺序,返回其中任意⼀种顺序即可。
字符串 s 字典顺序⼩于字符串 t 有两种情况:
• 在第⼀个不同字⺟处,如果 s 中的字⺟在这⻔外星语⾔的字⺟顺序中位于 t 中字⺟之前,那
么 s 的字典顺序⼩于 t 。
• 如果前⾯ min(s.length, t.length) 字⺟都相同,那么 s.length < t.length
时, s 的字典顺序也⼩于 t 。

⽰例1:
输⼊:words=["wrt","wrf","er","ett","rftt"]
输出:"wertf"
⽰例2:
输⼊:words=["z","x"]
输出:"zx"
⽰例3:
输⼊:words=["z","x","z"]
输出:""
解释:不存在合法字⺟顺序,因此返回""。

提⽰:
◦ 1 <= words.length <= 100
◦ 1 <= words[i].length <= 100
◦ words[i] 仅由⼩写英⽂字⺟组成

讲解算法原理

解法:
算法思路:

将题意搞清楚之后,这道题就变成了判断有向图时候有环,可以⽤拓扑排序解决。
如何搜集信息(如何建图):
a. 两层for循环枚举出所有的两个字符串的组合;
b. 然后利⽤指针,根据字典序规则找出信息。

编写代码

c++算法代码:

class Solution
{
 unordered_map<char, unordered_set<char>> edges; // 邻接表来存储图 unordered_map<char, int> in; // 统计⼊度
 bool cheak; // 处理边界情况
public:
 string alienOrder(vector<string>& words) 
 {
 // 1. 建图 + 初始化⼊度哈希表
 for(auto& s : words)
 {
 for(auto ch : s)
 {
 in[ch] = 0;
 }
 }
 int n = words.size();
 for(int i = 0; i < n; i++)
 {
 for(int j = i + 1; j < n; j++)
 {
 add(words[i], words[j]);
 if(cheak) return "";
 }
 }
 
 // 2. 拓扑排序
 queue<char> q;
 for(auto& [a, b] : in)
 {
 if(b == 0) q.push(a);
 }
 string ret;
 while(q.size())
 {
 char t = q.front(); q.pop();
 ret += t;
 for(char ch : edges[t])
 {
 if(--in[ch] == 0) q.push(ch);
 }
 }
 // 3. 判断
 for(auto& [a, b] : in)
 if(b != 0) return "";
 
 return ret;
 }
 void add(string& s1, string& s2)
 {
 int n = min(s1.size(), s2.size());
 int i = 0;
 for( ; i < n; i++)
 {
 if(s1[i] != s2[i])
 {
 char a = s1[i], b = s2[i]; // a -> b
 if(!edges.count(a) || !edges[a].count(b))
 {
 edges[a].insert(b); 
 in[b]++;
 }
 break;
 }
 }
 if(i == s2.size() && i < s1.size()) cheak = true;
 }
};

java算法代码:

class Solution
{
 Map<Character, Set<Character>> edges = new HashMap<>(); // 邻接表 Map<Character, Integer> in = new HashMap<>(); // 统计每个节点的⼊度 boolean check;
 public String alienOrder(String[] words) 
 {
 // 1. 初始化⼊度哈希表 + 建图
 for(String s : words)
 {
 for(int i = 0; i < s.length(); i++)
 {
 char ch = s.charAt(i);
 in.put(ch, 0);
 }
 }
 int n = words.length;
 for(int i = 0; i < n; i++)
 {
 for(int j = i + 1; j < n; j++)
 {
 add(words[i], words[j]);
 if(check == true) return "";
 }
 }
 // 2. 拓扑排序
 Queue<Character> q = new LinkedList<>();
 for(char ch : in.keySet())
 {
 if(in.get(ch) == 0) q.add(ch);
 }
 StringBuffer ret = new StringBuffer();
 while(!q.isEmpty())
 {
 char t = q.poll();
 ret.append(t);
 if(!edges.containsKey(t)) continue;
 for(char ch : edges.get(t))
 {
 in.put(ch, in.get(ch) - 1);
 if(in.get(ch) == 0) q.add(ch);
 }
 }
 // 3. 判断
 for(char ch : in.keySet())
 {
 if(in.get(ch) != 0) return "";
 }
 return ret.toString();
 }
 public void add(String s1, String s2)
 {
 int n = Math.min(s1.length(), s2.length());
 int i = 0;
 for( ; i < n; i++)
 {
 char c1 = s1.charAt(i), c2 = s2.charAt(i);
 if(c1 != c2)
 {
 // c1 -> c2
 if(!edges.containsKey(c1))
 {
 edges.put(c1, new HashSet<>());
 }
 if(!edges.get(c1).contains(c2))
 {
 edges.get(c1).add(c2);
 in.put(c2, in.get(c2) + 1);
 }
 break;
 }
 }
 if(i == s2.length() && i < s1.length()) check = true;
 }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2219566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机组成原理(笔记7高速缓冲存储器Cache,计算机组成原理的重难点全、直接、组相连)

为什么要设立高速缓冲存储器 &#xff08;Cache&#xff09;&#xff1f; Cache是介于CPU和主存之间的小容量存储器&#xff0c;存取速度比主存快。它能高速地向CPU提供指令和数据&#xff0c;加快程序的执行速度。它是为了解决CPU和主存之间速度不匹配而采用的一项重要技术。…

unity静态批处理

unity静态批处理 静态批处理要求和兼容性渲染管线兼容性 使用静态批处理在构建时进行静态批处理在构建时执行静态批处理的步骤&#xff1a; 在运行时进行静态批处理性能影响 静态批处理 静态批处理是一种绘制调用批处理方法&#xff0c;它将不移动的网格组合在一起&#xff0c…

【HarmonyOS NEXT】权限申请及应用设置页跳转

关键词&#xff1a;鸿蒙、程序访问控制、定位、应用详情页、startability、want 在app开发过程中&#xff0c;常进行系统权限的申请以提供设备访问或个性化功能&#xff08;如扫一扫、城市定位、剪贴板等&#xff09;&#xff0c;从而保障应用功能的完整性&#xff0c;那么本期…

mov 转 mp4

1. 下载 ffmpeg 下载链接 Tags GyanD/codexffmpeg GitHub 下载 windos 精简版 解压 &#xff08;里面的mov文件和mp4文件是我后面自己加的&#xff09; 2. 转换 转换命令 ffmpeg -i 5.mov -c:v libx264 -c:a aac 5.mp4 其中 5.mov 是源文件路径 5.mp4是目标路径 使用lib…

计算机毕业设计 零食批发商仓库管理系统的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

智发展 智飞跃 亚信安全与新华三深化战略合作

10月16日&#xff0c;亚信安全与新华三集团共同宣布&#xff0c;双方正式签署战略合作协议&#xff0c;双方将基于各自在硬件及软件安全领域的能力和优势&#xff0c;在产品、解决方案、市场拓展等多个领域深入合作&#xff0c;赋能千行百业数字化转型与变革。 亚信安全CEO马红…

跨域问题及常用的5种解决方案

1.什么是跨域问题&#xff1f; 跨域问题通常指的是在浏览器中由于同源策略的限制而产生的问题。同源策略&#xff08;Same-origin policy&#xff09;是浏览器的一种安全措施&#xff0c;它要求请求的域名、协议和端口必须与提供资源的网站相同。当一个网页尝试访问另一个来源…

【算法】C++中的二分查找

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

wifi、热点密码破解 - python

乐子脚本&#xff0c;有点小慢&#xff0c;试过多线程&#xff0c;系统 wifi 连接太慢了&#xff0c;需要时间确认&#xff0c;多线程的话系统根本反应不过来。 也就可以试试破解别人的热点&#xff0c;一般都是 123456 这样的傻鸟口令 # coding:utf-8 import pywifi from pyw…

初识git · 基本操作

目录 前言&#xff1a; 基本操作 检查是否存在git 初始化仓库 认识三个区域 添加文件 查看.git文件 修改文件 版本回退 撤销操作 删除文件 我的博客即将同步至腾讯云开发者社区&#xff0c;邀请大家一同入驻&#xff1a;https://cloud.tencent.com/developer/suppor…

Qt-多线程

1. Qt 多线程概述 Qt 默认只有一个主线程&#xff0c;该线程既要处理窗口移动&#xff0c;又要处理各种运算。 当要处理的运算比较复杂时&#xff0c;窗口就无法移动&#xff0c;所以在处理程序时在很多情况下都需要使用多线程来完成。 示例&#xff1a;移动窗口和复杂循环 …

八股面试2(自用)

mysql存储引擎 存储引擎&#xff1a;定义数据的存储方式&#xff0c;以及数据读取的实现逻辑 在以前数据库5.5默认MyISAM引擎&#xff0c;之后默认InnoDB引擎 MyISAM引擎的数据和索引是分开存储的&#xff0c;InnoDb将索引和文件存储在同一个文件。 MyISAM不支持事务&#…

SPOOLing技术详解,结合实际场景让你了解什么是假脱机技术。

SPOOLing技术 ​ 在手工操作阶段&#xff0c;主机直接从I/O设备获取数据&#xff0c;但是由于设备速度很慢&#xff0c;主机速度很快。人机速度矛盾明显&#xff0c;主机需要浪费很多时间来等待设备。 什么是脱机技术&#xff0c;脱机技术可以解决什么问题&#xff1f; 所谓脱…

大数据测试:Charles修改响应数据

上一篇大数据测试&#xff1a;Fiddler修改响应数据-CSDN博客 &#xff0c;有同学反馈有没有Charles的方式修改响应数据&#xff0c;本篇就是Charles修改数据操作步骤&#xff0c;相比较fiddler&#xff0c;Charles相对简单&#xff0c;便捷&#xff0c;我很喜欢 1、背景&…

【笔记】【YOLOv10图像识别】自动识别图片、视频、摄像头、电脑桌面中的花朵学习踩坑

&#xff08;一&#xff09;启动 创建环境python3.9 打开此环境终端 &#xff08;后面的语句操作几乎都在这个终端执行&#xff09; 输入up主提供的语句&#xff1a;pip install -r requirements.txt 1.下载pytorch网络连接超时 pytorch网址&#xff1a; Start Locally | P…

java -jar 命令自动重启 Java 项目

一、java -jar 方式运行项目 重启Java项目通常意味着你需要先停止当前运行的Java进程&#xff0c;然后再次启动它。下面是在CentOS上执行这些步骤的一种常见方法&#xff1a; 停止Java进程 找到Java进程的PID&#xff1a; 使用ps命令配合grep来查找运行中的Java进程的PID&#…

【Java SE 】封装 的特性 和 static 详解

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. 封装的概念 1.1 一个例子 2. 访问权限控制符 3. 包的概念 3.1 import 导入 3.2 常见的包 4. static 静态成员 4.1 static 使用情况 4.2 static 修…

> Invalid revision: 3.22.1-g37088a8-dirty

Android项目使用cmake 3.22.1&#xff0c;编译时报错&#xff1a; > Invalid revision: 3.22.1-g37088a8-dirty解决方法一&#xff1a; 升级Gradle版本和AGP的版本&#xff1b; 建议使用AS推荐的版本&#xff1a; 目前可运行的版本配置&#xff1a; AS&#xff1a;Jel…

champ模型部署指南

一、介绍 champ是由阿里巴巴、复旦大学和南京大学的研究人员共同提出的一种基于3D的将人物图片转换为视频动画的模型&#xff0c;该方法结合了3D参数化模型(特别是SMPL模型)和潜在扩散模型&#xff0c;能够精确地捕捉和再现人体的3D形状和动态&#xff0c;同时保持动画的时间一…

读书读到NOBEL

最近在读陈逸鹤的《程序员的自我修养》这本书&#xff0c;里面有这么一段话&#xff1a; “远古时代的人们只能创造出用于猎捕的长矛&#xff0c;而今天借助来自各行各业人 们的智慧&#xff0c;我们可以制造出高铁、大型飞机&#xff0c;并探索宇宙。但要更进一步解决人类所面…