文章目录
本专栏收录的均为牛客网的算法题目,内含链表、双指针、递归、动态规划、基本数据结构等算法思想的具体运用。牛客网不仅有大量的经典算法题目,也有大厂的面试真题,面试、找工作完全可以来这里找机会。此外,网站内的编码主题多样化,调试功能可运用性强,可谓是非常注重用户体验。这么好的免费刷题网站还不快入手吗,快去注册开启算法百炼成神之路吧!
学会使用邻接表解决图论问题,巧妙利用vector容器
题目链接:拓朴排序

解决拓扑排序之前要先认识什么是拓扑排序:
对一个有向无环图(Directed Acyclic Graph简称
DAG)图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
解决步骤:
inDegree表示每个顶点的入度。本题源码:
#include<iostream>
#include<vector>
#include<queue>
#define M 200001
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> adjList[M]; // 模拟邻接表
int inDegree[M] = { 0 };// 记录每个顶点的入度
int a, b;
for (int i = 0; i < m; i++) {
cin >> a >> b;
adjList[a].push_back(b);
inDegree[b]++;
}
queue<int> que; // 将初始入度为零的顶点入队
for (int i = 1; i <= n; i++) {
if (inDegree[i] == 0)
que.push(i);
}
int cnt = 0; // 用来计数,判断改图是否有环
vector<int> res; // 用来输出顶点序列
while (!que.empty()) {
int u = que.front();
que.pop();
res.push_back(u);
for (int i = 0; i < adjList[u].size(); i++) { // 遍历u的相邻顶点
int v = adjList[u][i];
if (--inDegree[v] == 0)
que.push(v);
}
cnt++;
}
// 若计数器与顶点数相同则图无环,存在拓扑排序
if (cnt == n) {
for (int i = 0; i < res.size(); i++) {
cout << res[i];
// 限制输出空格的条件
if (i != res.size() - 1) {
cout << " ";
}
}
} else {
cout << -1;
}
return 0;
}
重要注释:
adjList数组是vector类型的,用来模拟邻接表
vector容器模拟邻接表进行建图vector[a]所对应的数组中存储着该顶点所指向的其他顶点inDegree数组代表每一个顶点的入度情况BFS的思想:
题目链接:最小生成树

本题要求在最小花费下将 n 户人家连接起来,很显然是最小生成树的问题,我采用prim算法:
cost按权升序排序,那么cost[0][2]就是最小的一个权值unordered_set容器:
unordered_set 容器的元素是无序的,可以用来给顶点去重find 方法也很好用cost二维数组,直到所有顶点全部放入容器中,遍历结束本题源码:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 返回最小的花费代价使得这n户人家连接起来
* @param n int n户人家的村庄
* @param m int m条路
* @param cost intvector<vector<>> 一维3个参数,表示连接1个村庄到另外1个村庄的花费的代价
* @return int
*/
// 自定义排序规则:按权递增
static bool cmp(vector<int>& x, vector<int>& y) {
return x[2] < y[2];
}
int miniSpanningTree(int n, int m, vector<vector<int> >& cost) {
unordered_set<int> points; // 记录不重复的点
int res = 0;
sort(cost.begin(), cost.end(), cmp);
res += cost[0][2]; // 此时res 为最小权值
// 将最小边加入
points.insert(cost[0][0]);
points.insert(cost[0][1]);
while (1) {
if (points.size() == n)
break; // 所有的点连同后退出循环
// 遍历剩余的边
for (auto it = cost.begin(); it != cost.end(); it++) {
// 如果边仅有一个点在集合内就加入
if ((points.find((*it)[0]) != points.end() &&
points.find((*it)[1]) == points.end()) ||
(points.find((*it)[1]) != points.end() &&
points.find((*it)[0]) == points.end()))
{
res += (*it)[2];
points.insert((*it)[0]);
points.insert((*it)[1]);
cost.erase(it); // 删除该边
break;
}
}
}
return res;
}
};
重要注释:
cmp 是自定义的一个按权递增的排序函数,配合sort函数来将cost排序
auto关键字可以自动推导表达式类型,在这里就相当于vector<vector<int>>::iteratorif的条件很长,但其实就是将有且仅有一个顶点在points中的边找到:
points 中cost,直到全部顶点被插入到points中res 就是该题的结果,即最小花费。题目链接:单源最短路2


使用Dijkstra算法(即不断从未处理集合中找当前距离源点最近的顶点以添加到已处理集合中,直至未处理集合为空的算法思想)
dist记录每个顶点与源点的距离:
false,一经处理就设为truedist[n]就是顶点n到源点的最短距离本题源码
#include<iostream>
#include<climits> // 使用INT_MAX所需要引入的头文件
using namespace std;
const int N = 5000; // 注意题干,图的点数是固定值5000
int main() {
int G[N + 1][N + 1]; // 用于模拟邻接矩阵进行建图
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
G[i][j] = INT_MAX; // 先将邻接矩阵全部初始化为无穷大
}
}
int n, m;
cin >> n >> m;
int u, v, w;
for (int i = 1; i <= m; i++) {
cin >> u >> v >> w;
G[u][v] = w;
G[v][u] = w; // 需要关于主对角线对称,因此两边都需要存储
}
int dist[N + 1]; // 用于存储每个顶点当前与源点的最短距离
bool flag[N + 1]; // 用于记录每个顶点是否已经完成与源点最短距离的计算处理
for (int i = 1; i <= N; i++) {
dist[i] = G[1][i]; // 初始设置为邻接矩阵中源点所在 行 的权值
flag[i] = false;
}
dist[1] = 0;
flag[1] = true; // 将源点加入已处理集合
for (int i = 2; i <= N; i++) {
int tmp = INT_MAX, index = 1;
for (int j = 1; j <= N; j++) { // 遍历寻找与源点的最短距离
if (flag[j] == false && dist[j] < tmp) {
tmp = dist[j];
index = j;
}
}
if (index != 1) {
flag[index] = true; // 找到后将其加入已处理集合
}
for (int j = 2; j <= N; j++) {
if (flag[j] == false && G[index][j] != INT_MAX) {
if (G[index][j] + dist[index] < dist[j]) {
dist[j] = G[index][j] + dist[index]; // 更新最短路径
}
}
}
}
if (dist[n] != INT_MAX) {
cout << dist[n];
} else {
cout << -1;
}
return 0;
}
重要注释:
G是具化出的邻接矩阵,将元素值全部初始化为无穷大:INT_MAXu,v记录两个顶点,w记录顶点间距离,全部存入G中dist数组用来存放各顶点到源点的距离,flag数组记录顶点是否被处理过index代表着与源点连接且距离最短的未经处理的顶点:
index寻找与之相连且未经处理的顶点:
dist[index]是index到源点的最短距离,如果加上与之相连的顶点的距离较小,那么就更新最短路径dist数组的值就是各点到源点的最短路径当自己动手去做的时候才发现原来我以为的难题,不过如此,将这份自信传达给大家,奋斗下去!
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun