![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
rookie_yanyu
这个作者很懒,什么都没留下…
展开
-
crossing-ray方法判断点在封闭多边形内部
计算机图形学,判断点在封闭多边形内部。原创 2022-06-26 23:55:57 · 347 阅读 · 1 评论 -
利用CyclicBarrier实现赛马游戏
赛马游戏前言最近在看CountDownLatch和CyclicBarrier相关的锁知识,看到网上有通过CyclicBarrier特性实现一个赛马游戏,觉得很有意思,就把他搬运过来。背景多匹马一起赛跑,每匹马每一次都可以跑随机个距离,看哪匹马最先到达终点。代码import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.concurrent.CyclicBarrier;i原创 2021-09-15 20:27:09 · 177 阅读 · 0 评论 -
最短路径之Bellman-Ford算法
Bellman-Ford算法优点能够解决最短路径问题中边权值为负的情况代码简单缺点相较于Dijkstra时间复杂度较高(O(VE)),V表示结点数,E表示边数。步骤距离初始化,源点初始化零值,其他点初始化为无穷大;对所有边进行松弛,松弛n - 1次(n - 1依据理论证明得出);进行负权环判断。代码#include <bits/stdc++.h>using namespace std;const int INF = 99999;vector<int&原创 2021-04-25 00:31:04 · 109 阅读 · 0 评论 -
数据结构之线段树
线段树前言 线段树这种数据结构主要的用来对区间的查询和更新同时进行优化的。 如果仅仅需要对查询进行优化,那么使用前缀和就可以使单次查询的时间复杂度达到O(1)。 如果是考虑更新操作那么要分成两种情况:单点更新,区间更新。无论是单点更新还是区间更新,最坏的时间复杂度达到了O(n)。 那么我们就考虑使用线段树这种数据结构来优化查找和更新操作。 在线段树中查找的时间复杂度为:O(logn);更新(单点更新和区间更新)的时间复杂度均为:O(logn)。 线段树的空间复杂度为O(n),但是一原创 2021-04-17 12:34:21 · 296 阅读 · 0 评论 -
螺旋矩阵常数复杂度解法
螺旋矩阵吐槽昨天参加leetcode编程大赛,做到这题,本想着使用模拟法解决,一看数据规模达到10^9,我有预感这题应该是数学解法,那么我就不会了,之后上网查文档,发现这题是一种数学问题,看了别人的论文,想套用别人的公式,一顿提交,疯狂WA,心态爆炸,现在觉得把这题的O(1)时间复杂度的解法写出来,希望之后有人碰到这个问题时可以不用去筛各种帖子。。。题意一个 n 行 n 列的螺旋矩阵可由如下方法生成:从矩阵的左上角(第 0 行第 0 列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,原创 2021-04-06 19:49:54 · 259 阅读 · 0 评论 -
常用算法之正则表达式匹配
正则表达式匹配介绍请实现一个函数用来匹配包含’. ‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。示例 1:输入:s = “aa”p = “a”输出: false解释: “a” 无法匹配 “aa” 整个字符串。示例 2:输入:s = “aa”p = “a*”输出: true解释原创 2021-03-31 15:15:21 · 188 阅读 · 0 评论 -
交换值的三种方法
交换值的三种方法吐槽今天做题时又碰到了两个数交换位置的情况,当我使用C++的时候可以选择使用swap()函数,一劳永逸。但是当我用Java时,老是得自己手动写函数来交换两者的位置,还有一点就是,对于基本类型,函数的参数列表是传值的,无法进行位置的交换,所以多数时候基本没法单独写一个函数模块,所以必须要把这段无趣的代码写在代码逻辑内部,我写了三种交换两个位置的方法(其实华而不实,但还是默默记下。。。)。方法一(常用)使用中间变量代码一void swap(int a,int b){ // a =原创 2021-03-09 14:39:49 · 762 阅读 · 0 评论 -
最短路径问题之Dijkstra算法
Dijkstra算法吐槽今天参加了leetcode周赛,第三题一眼就看出需要使用到一点到多点的最短距离,第一反应就是Dijkstra算法,奈何平时基本没写过几遍Dijkstra算法,模本没整理好,导致手忙脚乱,四处考古,最后压时提交,还是WA…,很烦,所以花时间把Dijkstra算法,完整的写一遍。后续可能还会把Floyd算法,SPFA算法,Bellman-Ford算法手撕一遍,做到基本图论问题一网打尽。简介解决什么问题一个图中,求一点到其他点的最短距离。PS:如果仅求一个点到另一个点的最短距离原创 2021-03-07 18:46:35 · 195 阅读 · 0 评论 -
动态规划之背包问题
背包问题问题描述有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?假定4个物品,背包最大容量是8。体积分别为{2,3,4,5},价值分别为{3,4,5,6}。0-1背包问题问题:在有限容量capacity中,每个物品最多取一次,使得背包中物品的价值最大。代码#include <bits/stdc++.h>using namespace std;vector<int> w{2,3,4,5};vector<int原创 2021-02-28 21:34:50 · 210 阅读 · 0 评论 -
与状态压缩问题相关的小trick:二进制子集
二进制子集:状态压缩中可能涉及到的常用小trick。问题解析假设二进制状态为bitmask = 10101(对应十进制为 13),那么其子集为{00001,00100,10000,00101,10001,10100,10101}。对应子集的十进制为{1,4,8,5,9,12,13}。根据组合排列原理,已知1的个数有3个,那么我们知道它的子集中元素个数为2^3 - 1,1的个数有n个,那么子集中元素个数为2^n - 1。如何找出该二进制状态的子集呢?代码#include <bits/s原创 2021-02-26 20:09:28 · 84 阅读 · 0 评论 -
数据结构之优先队列
优先队列模板模板:priority_queue<Type, Container, Functional>Type:进入队列的数据类型Container:保存数据的容器(一般vector,deque,不能使用list)Functional:元素比较方式默认比较方式一般默认priority_queue(默认大顶堆):以int为例:priority_queue : 大顶堆实现,等价于priority_queue<int,vector,less>,出队列时元素会按照从大到小顺原创 2021-02-24 21:04:18 · 92 阅读 · 0 评论 -
经典算法之字典树
字典树(TrieTree)简介字典树(前缀树)是字符串匹配问题的常用算法之一,是KMP算法的升级版本,KMP解决单一字符串匹配问题效果极佳,但是对于多个字符串匹配的问题,需要使用字典树效果才显著。代码#include <bits/stdc++.h>using namespace std;const int NUM = 26;typedef struct TrieNode{ bool isWord; struct TrieNode *next[NUM]; TrieNode()原创 2021-01-28 09:54:19 · 921 阅读 · 0 评论 -
图论之克鲁斯卡尔(kruskal)算法
最小生成树之克鲁斯卡尔算法例题给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。示例 1:输入:points = [[0,0],[2,2],[3,10],[5,2],[7原创 2021-01-20 20:58:35 · 322 阅读 · 0 评论 -
常用算法之并查集
并查集代码#include <bits/stdc++.h>using namespace std;class UF{private: vector<int> parent; vector<int> size; int count;public: UF(int n){ this->count = n; parent = vector<int>(n); size = vector<int>(n); for (原创 2021-01-11 20:40:49 · 108 阅读 · 2 评论 -
基本算法之树的遍历
二叉树的前、中、后序遍历前言二叉树是数据结构学习中绕不开的话题。在二叉树的众多题目中,使用dfs(深度优先搜索)和bfs(广度优先搜索)是最常用的,那么学会如何搜索二叉树是必不可少的。二叉树的搜索分为前,中,后序遍历,又分别对应有递归版本和迭代版本。前序遍历遵循的原则是:根节点—>左子节点—>右子节点。中序遍历遵循的原则是:左子节点—>根节点—>右子节点。后续遍历遵循的原则是:左子节点—>右子节点—>根节点。代码#include <bits/stdc原创 2020-12-28 10:54:59 · 77 阅读 · 0 评论 -
基本算法之二叉树的序列化和反序列化
二叉树的序列化和反序列化作用由于树结构是二维的,在输入输出时,这样的结构不是很好表示,所以需要使用一种方式将树结构转换成一种易于输入输出的形式表示,同时不失树的结构特性。把树转换成线性结构单元(如数组)称做序列化,把线性结构单元(如数组)还原成树结构称作反序列化。代码#include <bits/stdc++.h>using namespace std;// 二叉树结构typedef struct TreeNode{ int val; TreeNode *lef原创 2020-12-26 18:26:36 · 92 阅读 · 0 评论 -
基本算法之KMP算法
KMP算法作用字符串匹配算法,暴力搜索的时间复杂度达到O(n^2),KMP算法时间复杂度O(m + n),其中n是待查找的字符串长度,m是需要匹配的字符串长度。代码#include <bits/stdc++.h>using namespace std;class KMP{private: vector<vector<int> > dp; string pat;public: KMP(string& pat){ this->pat原创 2020-12-23 20:24:39 · 177 阅读 · 0 评论 -
数据结构之单调队列
单调队列代码#include <bits/stdc++.h>using namespace std;class MonotonicQueue{ deque<int> data_;public: void push(int e){ while (!data_.empty() && e > data_.back()) data_.pop_back(); data_.push_back(e); return ; } void pop(v原创 2020-12-23 20:13:46 · 93 阅读 · 0 评论 -
排序算法之基数排序
基数排序前言通常数据结构和算法课程中会涉及到多种排序算法,一般有冒泡排序、简单插入排序、选择排序、希尔排序、归并排序、堆排序、快速排序等,时间复杂从O(n)降至O(nlogn)。这次介绍的基数排序和前文介绍的各种排序算法最大的不同在于时间复杂度仅为O(n)。前提条件我们为了讲清楚这个排序算法,假设待排序的数为非负数(大于等于零),取值范围为int类型(32位)。基本思路首先我们需要开辟10个桶,以供比较之用。由于假设待比较的数字只有32位,那么我们最多只需要比较10轮,每轮比较后将数字按序存放原创 2020-12-06 23:24:27 · 117 阅读 · 0 评论 -
数据结构之稀疏表
数据结构之稀疏表适用场景稀疏表解决的是区间最值问题(RMQ),对于多次查找区间最值的场景,稀疏表的作用是能够优化时间复杂度,常规的单次查找区间最值的时间复杂度为O(n),使用稀疏表能够将单次区间最值的查找时间均摊到O(logn)。当然对于区间最值查找的优化还存在诸如线段树等数据结构。基本思路稀疏表的构成主要分两个部分,一、建表,二、查找。建表建表:采用动态规划的方式建表。以查找区间内的最小值为例,采用倍增法的思想。待查找的数组为nums,定义二维数组f[i][k]。含义:起始位置为i,区间长度为原创 2020-12-04 22:57:23 · 2022 阅读 · 0 评论 -
基本算法之二分查找
二分查找查找方式有哪些,效率如何二分查找的前提条件二分查找的形式以及代码实现后记查找方式有哪些,效率如何 不同的数据结构有不同的查找效率。 1.底层数据结构是以数组实现的,那么其查找数组下标效率为O(1),查找特定值得效率为O(n) 2.底层数据结构是以链表实现的,那么其查找迭代器(类似于数组查询下标)效率为O(n),查找特定值得效率为O(n) 3.底层数据结构是以哈希表实现的,那么其查找迭代器和特定值效率均为O(1) 当然,以上查找效率只是针对于简单的数据结构而言,优化过的数据结构原创 2020-12-01 16:05:34 · 129 阅读 · 0 评论