自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(35)
  • 收藏
  • 关注

原创 crossing-ray方法判断点在封闭多边形内部

计算机图形学,判断点在封闭多边形内部。

2022-06-26 23:55:57 414 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 201

原创 对象性能模式之享元模式

享元模式享元模式是池技术的重要实现方式,可以降低大量重复的、细粒度的类在内存中的开销。享元模式的优点大幅度减少内存中对象的数量,降低程序内存的占用,提高性能。享元模式的缺点享元模式增加了系统的复杂性,需要分出外部状态和内部状态。享元模式将享元对象的状态外部化,而读取外部状态使得运行时间变长。享元模式的使用场景系统有大量的相似对象,这些对象耗费大量的内存。细粒度的对象都具备较接近的外部状态,而内部状态与环境无关,即对象没有特定身份。需要缓冲池的场景。示例代码棋子接口pub

2021-07-29 23:53:06 123

原创 RocketMQ

RocketMQ作用应用解耦流量削峰数据分发缺点系统的可用性降低系统复杂度提高一致性问题和其他MQ的比较RocketMQ开发语言:java、单机吞吐量:10万级、时效性:ms级、可用性:非常高(分布式架构)、功能特性:MQ功能比较完备,扩展性佳。集群搭建producer:消息的发送者consumer:消息接受者broker:暂存和传输消息nameServer:管理brokertopic:区分消息的种类message queue:相当于topic的分区,用于并行发送和接

2021-07-28 21:45:49 110

原创 对象创建之工厂方法

工厂方法定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。工厂方法的优点良好的封装性,代码结构清晰。优秀的可扩展性。屏蔽产品类。产品类的实现如何变化,调用者都不需要关心。只需要关心产品接口。工厂方法模式是典型的解偶框架。高层模块只需要知道产品的抽象类,其他实现类都不用关心。工厂方法的使用场景工厂方法模式是new一个对象的替代品,因此所有需要生成对象的地方都可以使用。需要灵活的、可扩展的框架时,可以考虑采用工厂方法模式。工厂方法可以用在异构项目

2021-07-27 23:36:39 157

原创 单一职责模式之桥模式

桥模式将抽象和实现解耦,使得两者可以独立地变化。桥模式的优点抽象和实现分离是桥模式的主要特点,是为了解决继承的缺点而提出的设计模式。实现对客户透明,客户端不用关系细节的实现。提高灵活性和扩展性。使用场景如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。设计要求实现化角色的任何改变不应当影响客户端。一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。不希望或不适合使用继承的场合。示例代码抽象图形类p

2021-07-26 23:47:44 79

原创 单一职责模式之装饰器模式

装饰器模式动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式比生成子类更为灵活。装饰器的优点装饰类和被装饰类可以独立发展,而不会相互耦合。装饰器模式是继承关系的一个替代方案。装饰器模式可以动态地扩展一个实现类的功能。装饰器的缺点多层装饰是比较复杂的。装饰器的使用场景。需要扩展一个类的功能,或给一个类增加附加功能。需要动态地给一个对象增加功能,这些功能可以在动态地撤销。需要为一批类进行改装或加装功能。装饰器模式是对继承的有力补充。单纯使用继承时,在一些情况下就会增加

2021-07-22 23:57:09 108

原创 组件协作之观察者模式

观察者模式定义又叫做发布订阅模式。项目中经常使用。定义了对象间的一对多的依赖关系,每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。观察者模式的优点观察者和被观察者之间是抽象耦合。耦合关系通过接口来维系。支持广播通信。观察者模式的缺点如果一个主题有多个直接或者间接的观察者,则通知所有的观察者会花费很多时间,且开发和调试都比较复杂。如果主题之间有循环依赖,被观察者会触发它们之间进行循环调用,导致系统崩溃。如果对观察者的通知是通过另外的线程进行异步投递的,系统必须

2021-07-20 00:02:41 102

原创 Stream流

allMatch()/** * allMatch()流中的元素必须全部符合筛选条件,才能返回true; * 否则,返回false。 */public class AllMatchTest { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4,5); boolean res = list.stream().allMatch(e .

2021-07-05 22:31:25 63

原创 Google Guava

集合类Immutable:不可变类型public class Immutable { public static void main(String[] args) { System.out.println("immutableList:"); List<Integer> list = ImmutableList.of(1,2,3,4); // list.add(1); error list.stream().forEa.

2021-07-01 23:37:12 130

原创 缓存和数据库的一致性问题

缓存和数据库的双写一致性参考:https://www.cnblogs.com/yanglang/p/9098661.html前言最近在实习,为了能在项目中写出简洁的代码,正在学习Google Guava这个工具包,看到了Cache这一块,就想起了这个面试常问的有关缓存和数据库的题,现在做一个温故知新,查阅了网络上相关文档,整理一下。读取数据流程读请求过来会首先请求缓存,如果缓存中存在数据,那么就将数据返回给客户端;否则,去请求数据库服务器,如果数据库中也没有数据,将空值返回给客户端;如果数据库中存

2021-06-29 00:02:54 101

原创 最短路径之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 131

原创 数据结构之线段树

线段树前言  线段树这种数据结构主要的用来对区间的查询和更新同时进行优化的。  如果仅仅需要对查询进行优化,那么使用前缀和就可以使单次查询的时间复杂度达到O(1)。  如果是考虑更新操作那么要分成两种情况:单点更新,区间更新。无论是单点更新还是区间更新,最坏的时间复杂度达到了O(n)。  那么我们就考虑使用线段树这种数据结构来优化查找和更新操作。  在线段树中查找的时间复杂度为:O(logn);更新(单点更新和区间更新)的时间复杂度均为:O(logn)。  线段树的空间复杂度为O(n),但是一

2021-04-17 12:34:21 341

原创 螺旋矩阵常数复杂度解法

螺旋矩阵吐槽昨天参加leetcode编程大赛,做到这题,本想着使用模拟法解决,一看数据规模达到10^9,我有预感这题应该是数学解法,那么我就不会了,之后上网查文档,发现这题是一种数学问题,看了别人的论文,想套用别人的公式,一顿提交,疯狂WA,心态爆炸,现在觉得把这题的O(1)时间复杂度的解法写出来,希望之后有人碰到这个问题时可以不用去筛各种帖子。。。题意一个 n 行 n 列的螺旋矩阵可由如下方法生成:从矩阵的左上角(第 0 行第 0 列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,

2021-04-06 19:49:54 288

原创 常用算法之正则表达式匹配

正则表达式匹配介绍请实现一个函数用来匹配包含’. ‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(含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 224

原创 随机函数相关题

Rand()1.拒绝采样用rand7()实现rand10()#include <bits/stdc++.h>using namespace std;int rand7(){ return rand() % 7 + 1;}int rand10(){ // (randX - 1) * Y + rand7() 可以实现randX_Y() while (true){ int a = rand7(); int b = rand7(); int num = (a - 1)

2021-03-16 21:17:59 114

原创 单例模式

单例模式介绍  单例模式是常用的设计模式之一。  作用就是确保一个类就这一个实例,并自行实例化且向整个系统提供这个实例。  两种类型:饿汉式(类加载时就进行对象实例化)、懒汉式(第一次引用类时才进行对象实例化)。  饿汉式资源利用效率上稍差,但是速度和反应时间上稍好。饿汉式容易在Java中实现,不易在C++中实现。Java中一般默认是懒汉式,但是饿汉式才更加符合Java语言的特点。代码饿汉式public class Singleton{ // 类加载时直接对象实例化 private st

2021-03-12 16:41:49 91

原创 MySQL索引底层数据结构之B+树

B+树哈希索引  当我们查询数据的时候,单点数据查询效率最高的是哈希索引,时间复杂度O(1),但是当查询数据是一个范围的话,那么由于哈希表的数据组织结构是无序的,对于范围查询不友好,必须全表扫描。效率低下。二分查找  为了克服这个缺点,需要有序的数据结构来实现范围查询,想到有序数组的二分查找,时间复杂度是O(logn),此时对于数组的增加、插入、删除等效率较低,时间复杂度O(n)。二叉搜索树(BST)  那么又提出新的数据结构BST(二叉搜索树),查找,增加,删除,插入时间复杂度都在O(logn

2021-03-11 22:00:45 146

原创 交换值的三种方法

交换值的三种方法吐槽今天做题时又碰到了两个数交换位置的情况,当我使用C++的时候可以选择使用swap()函数,一劳永逸。但是当我用Java时,老是得自己手动写函数来交换两者的位置,还有一点就是,对于基本类型,函数的参数列表是传值的,无法进行位置的交换,所以多数时候基本没法单独写一个函数模块,所以必须要把这段无趣的代码写在代码逻辑内部,我写了三种交换两个位置的方法(其实华而不实,但还是默默记下。。。)。方法一(常用)使用中间变量代码一void swap(int a,int b){ // a =

2021-03-09 14:39:49 790

原创 代理模式

代理模式简介代理模式是常用的设计模式。能够在不改变源代码的情况下对系统进行功能扩展。Java中代理模式分:静态代理和动态代理。动态代理使用Java反射机制实现,目前还没完全掌握。。。这里就讨论静态代理吧。示意图代码分析中间接口// 接口:沟通具体实现类和代理类,系统的设计仅仅依赖于该接口,// 而不关心接口中方法的具体实现,该接口可以看做不变的事物,// 具体实现类是在业务变更时频繁改变的。// 此时实现了代理类和具体实现类之间的松耦合。public interface IGameP

2021-03-07 19:38:29 154 1

原创 最短路径问题之Dijkstra算法

Dijkstra算法吐槽今天参加了leetcode周赛,第三题一眼就看出需要使用到一点到多点的最短距离,第一反应就是Dijkstra算法,奈何平时基本没写过几遍Dijkstra算法,模本没整理好,导致手忙脚乱,四处考古,最后压时提交,还是WA…,很烦,所以花时间把Dijkstra算法,完整的写一遍。后续可能还会把Floyd算法,SPFA算法,Bellman-Ford算法手撕一遍,做到基本图论问题一网打尽。简介解决什么问题一个图中,求一点到其他点的最短距离。PS:如果仅求一个点到另一个点的最短距离

2021-03-07 18:46:35 212

原创 动态规划之背包问题

背包问题问题描述有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 235

原创 与状态压缩问题相关的小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 105

原创 数据结构之优先队列

优先队列模板模板: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 117

原创 经典算法之字典树

字典树(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 960

原创 图论之克鲁斯卡尔(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 359

原创 常用算法之并查集

并查集代码#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 127 2

原创 基本算法之树的遍历

二叉树的前、中、后序遍历前言二叉树是数据结构学习中绕不开的话题。在二叉树的众多题目中,使用dfs(深度优先搜索)和bfs(广度优先搜索)是最常用的,那么学会如何搜索二叉树是必不可少的。二叉树的搜索分为前,中,后序遍历,又分别对应有递归版本和迭代版本。前序遍历遵循的原则是:根节点—>左子节点—>右子节点。中序遍历遵循的原则是:左子节点—>根节点—>右子节点。后续遍历遵循的原则是:左子节点—>右子节点—>根节点。代码#include <bits/stdc

2020-12-28 10:54:59 103

原创 基本算法之二叉树的序列化和反序列化

二叉树的序列化和反序列化作用由于树结构是二维的,在输入输出时,这样的结构不是很好表示,所以需要使用一种方式将树结构转换成一种易于输入输出的形式表示,同时不失树的结构特性。把树转换成线性结构单元(如数组)称做序列化,把线性结构单元(如数组)还原成树结构称作反序列化。代码#include <bits/stdc++.h>using namespace std;// 二叉树结构typedef struct TreeNode{ int val; TreeNode *lef

2020-12-26 18:26:36 111

原创 程序员算法趣题之Q04切分木棒

Q04切分木棒题目假设要把长度为 n 厘米的木棒切分为 1 厘米长的小段,但是 1 根木棒只能由 1 人切分,当木棒被切分为 3 段后,可以同时由 3 个人分别切分木棒(图 2)。求最多有 m 个人时,最少要切分几次。譬如 n = 8,m= 3 时如图所示,切分 4 次就可以了。当 n = 20, m = 3 时的最少切分次数为 _____ ;当 n = 100, m = 5 时的最少切分次数为 _____ 。答案:8、22代码#include <bits/stdc++.h>u

2020-12-24 11:20:26 356 1

原创 基本算法之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 199

原创 数据结构之单调队列

单调队列代码#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 115

原创 排序算法之基数排序

基数排序前言通常数据结构和算法课程中会涉及到多种排序算法,一般有冒泡排序、简单插入排序、选择排序、希尔排序、归并排序、堆排序、快速排序等,时间复杂从O(n)降至O(nlogn)。这次介绍的基数排序和前文介绍的各种排序算法最大的不同在于时间复杂度仅为O(n)。前提条件我们为了讲清楚这个排序算法,假设待排序的数为非负数(大于等于零),取值范围为int类型(32位)。基本思路首先我们需要开辟10个桶,以供比较之用。由于假设待比较的数字只有32位,那么我们最多只需要比较10轮,每轮比较后将数字按序存放

2020-12-06 23:24:27 131

原创 数据结构之稀疏表

数据结构之稀疏表适用场景稀疏表解决的是区间最值问题(RMQ),对于多次查找区间最值的场景,稀疏表的作用是能够优化时间复杂度,常规的单次查找区间最值的时间复杂度为O(n),使用稀疏表能够将单次区间最值的查找时间均摊到O(logn)。当然对于区间最值查找的优化还存在诸如线段树等数据结构。基本思路稀疏表的构成主要分两个部分,一、建表,二、查找。建表建表:采用动态规划的方式建表。以查找区间内的最小值为例,采用倍增法的思想。待查找的数组为nums,定义二维数组f[i][k]。含义:起始位置为i,区间长度为

2020-12-04 22:57:23 2131

原创 基本算法之二分查找

二分查找查找方式有哪些,效率如何二分查找的前提条件二分查找的形式以及代码实现后记查找方式有哪些,效率如何 不同的数据结构有不同的查找效率。 1.底层数据结构是以数组实现的,那么其查找数组下标效率为O(1),查找特定值得效率为O(n) 2.底层数据结构是以链表实现的,那么其查找迭代器(类似于数组查询下标)效率为O(n),查找特定值得效率为O(n) 3.底层数据结构是以哈希表实现的,那么其查找迭代器和特定值效率均为O(1) 当然,以上查找效率只是针对于简单的数据结构而言,优化过的数据结构

2020-12-01 16:05:34 169

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除