算法基础
文章平均质量分 51
郭同学如是说
在这里亟需一个宏大的的沉思。
展开
-
【大厂HOT100题】LRU 缓存
原题链接:LRU缓存题意LRU算法简介:LRU 全称:Least Recently Used,最近最少使用LRU是一种常用的页面置换算法,选择最近最少使用的页面予以淘汰题目要求完成以下函数功能:LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。void put(int key, int value) 如果关键字已原创 2021-12-27 00:04:01 · 330 阅读 · 0 评论 -
【大厂HOT100题】无重复字符的最长子串
原题链接:无重复字符的最长子串题意:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。思路暴力枚举:[i,j]可以记录一个区间,如果暴力枚举的话,就成了n个人之间任取两个人握手的问题,则算法复杂度为O(n2)O(n^2)O(n2)哈希表+双指针算法优化:枚举出以j为结尾的区间,使得[i,j]为无重复字符的最长子串。如果j++后使得[i,j]不满足为无重复字符的最长子串,则必定要i++,直到满足条件对字符的个数统计使用unordered_map完成cnt用于个数原创 2021-12-24 16:01:21 · 217 阅读 · 0 评论 -
【大厂HOT100题】反转链表 Reverse Linked List
原题连接:反转链表题意:给你单链表的头节点 head ,反转链表,并返回反转后的链表思路首先特判,如果head为空指针或者head->next为NULL则直接返回head使用两个指针,分别指向第一个结点la和第二个结点lb,让第二个结点的next结点指向第一个结点使用while循环持续该操作,直到遍历到最后一个结点。为了完成这个操作,需要一个temp指针变量临时存储lb->next最终,将head指向null,返回la即可/** * Definition for si原创 2021-12-23 22:41:11 · 323 阅读 · 0 评论 -
【大厂HOT100题】数组中的第K个最大元素
原题连接:数组中的第K个最大元素题意:给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。思路一:快速排序手写快排,返回nums[k-1]即可三分钟学会快速排序(图示讲解,附代码,通俗易懂)class Solution {public: void quick_sort(vector<int> &nums,int l,int r) { if(原创 2021-12-22 18:00:33 · 324 阅读 · 0 评论 -
弗洛伊德算法求最短路径
算法简介可以解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题算法的时间复杂度为O(N3)O(N^3)O(N3),空间复杂度为O(N2)O(N^2)O(N2)。与迪杰斯特拉算法不同的是,迪杰斯特拉算法只能求单源最短路径,并且不能处理负权边算法思想动态规划的思想设 Di,j,kD_{i, j, k}Di,j,k 为从 iii 到 jjj 的只以 (1..k)(1 . . k)(1..k) 集合中的节点为中间节点的最短路径的长度。若最短路径经过原创 2021-07-21 20:58:11 · 195 阅读 · 0 评论 -
迪杰斯特拉算法求最短路
思路邻接矩阵记录图信息维护两个顶点集合S和Q,S保留所有已知实际最短路径值的顶点,Q保留其他节点,dist[i]数组记录初始节点到i节点的距离,st[i]标记第i个节点是否是已知最短距离的节点初始化:dist[1]=0,其余点置为无穷,st数组全零,表示皆为未知最短距离n次循环:每次都在未确定最短路的点中找到一个路径最短的点,找到后用该点更新能到达的距离代码#include <iostream>#include <cstring>using namespace原创 2021-06-01 18:02:08 · 161 阅读 · 0 评论 -
宽度优先搜索得到有向图的拓扑序列
问题背景给定一个 n 个点 m 条边的有向图,点的编号是 1 到 n,图中可能存在重边和自环。请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出 −1。若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x 在 A 中都出现在 y 之前,则称 A 是该图的一个拓扑序列。思路几个性质:DAG (有向无环图)必定有一个拓扑序列拓扑序列不唯一算法步骤:用d数组记录每个点的入度,如果有某个点的入度是0,那么可以取出放在答案序列res中首先是遍历操作,把每个入原创 2021-06-01 15:34:41 · 152 阅读 · 0 评论 -
宽度优先搜索求图中点的层次
问题背景给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。所有边的长度都是 1,点的编号为 1∼n。请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 −1。思路用vector模拟邻接表存储图宽度优先搜索比较容易解决层序遍历的问题使用st数组标记点是否被遍历过,最先遍历的点一定是距离最短的,因此要加一个判断dist数组标记从点1到点i的距离,初始化为dist[1]=0,此后每往后遍历一个节点,它的距离都+1代码#include <io原创 2021-06-01 15:22:43 · 143 阅读 · 0 评论 -
【数据结构】数组模拟堆
大根堆/小根堆定义大根堆:任意一个节点的值大于等于它的子节点的值的二叉堆小根堆:任意一个节点的值小于等于它的子节点的值的二叉堆数组存储树结构根节点在数组中的位置是1第n个位置的子节点分别在2n和 2n+1,因此,第1个位置的子节点在2和3,第2个位置的子节点在4和5,以此类推节点n的父节点为n/2(向下取整)up操作如图,该二叉堆是一个大根堆(数字代表节点值)假设节点值被修改为2,那么2要被调整到上面,也就是所谓的up操作down操作接上,如果该节点被修改为8,那么原创 2021-05-21 18:36:35 · 167 阅读 · 0 评论 -
【基础算法】并查集
定义并查集是一种数据结构,可以高效的实现对【集合】的【并】与【查】操作查找(Find):确定某个元素处于哪个子集;合并(Union):将两个子集合并成一个集合。实现思路p[i]为i节点的父节点的值每一个集合都可以用一个树表示p[i]=i表示该节点为所在集合的树的根节点给数组p初始化赋值,设其值为p[i]=i,也即是说,p[1]=1,p[2]=2,以此类推。如果p[2]=1,p[3]=2则有:3节点的父节点为2,2节点的父节点为1,1节点的父节点为1,因此1为根节原创 2021-05-11 20:14:14 · 123 阅读 · 0 评论 -
LeetCode 300. 最长上升子序列 【动态规划】
【LeetCode 300. 最长递增子序列】题目要求给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。示例 1:输入:nums = [10,9,2,5,3,7,101,18]输出:4解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。示例 2:输入:nums = [0,1,0,3,2,3]输出:4示原创 2021-05-07 00:03:06 · 205 阅读 · 0 评论 -
数组模拟栈与队列
数组模拟栈#include <iostream>using namespace std;const int N=1e5+10;int s[N],tt;void push(int x){ s[++tt]=x;}void pop(){ --tt;}bool isempty(){ return tt;}int query(){ return s[tt];}int main(){ int n;cin>>n;原创 2021-05-02 10:28:23 · 76 阅读 · 0 评论 -
单调栈问题
问题链接问题描述给定一个长度为 N 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。问题思路维护一个单调递增的栈(因为需要输出的是左边第一个比它小的数)对于每个元素x,作如下检查:若栈不为空且栈顶元素大于等于x,执行pop操作如果此时栈空了,说明没有数满足小于x,因此输出-1如果此时栈不为空,说明有数满足小于x,且该数是第一个比它小的数,那么就输出它最后,将x入栈代码#include <iostream>#include <stack>原创 2021-05-01 19:23:45 · 162 阅读 · 0 评论 -
用数组模拟链表
为什么使用数组模拟链表struct node{ int val; node *next;};对于上面这种数据结构,也即动态分配链表地址空间的new node操作费时,而算法题的时间要求较高,因此采用耗时短的数组模拟链表(也即是静态链表)的方式数组模拟的链表同时还可以模拟邻接表,邻接表的本质是n个由数组模拟的链表,可以用来存储树和图e[i]:存储节点i的值ne[i]:存储节点i的下一个节点head表示头结点的下标idx表示当前用到的点链表初始化// 初始化void init(原创 2021-05-01 15:39:07 · 143 阅读 · 0 评论 -
区间合并问题
问题描述给定 n 个区间 [li,ri],要求合并所有有交集的区间。注意如果在端点处相交,也算有交集。输出合并完成后的区间个数。例如:[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。思路创建结构体数组,读入数据,并排序结构体数组(以左端数值为关键字从小到大进行排序)排序后有三种情况:– 1、可以合并– 2、可以合并– 3、不能合并,当做两个区间处理遍历数组– 如果下一个区间的左端在上一个区间内,那么更新右端最大值,对应1、2情况– 否则说明下一个区间的左端在上一个原创 2021-05-01 11:37:27 · 442 阅读 · 1 评论 -
结构体排序的几种常见形式
通过重载 < 操作符struct node{ int math; int chinese; bool operator < (const node &a) const { return math<a.math;//math从小到大进行排序 }};自定义sort的cmp函数对于一个结构体而言,有多个关键字,在使用sort的时候可以针对不同关键字进行排序比如下面这个结构体node存储数学和语文成绩struct no原创 2021-04-30 21:52:42 · 301 阅读 · 1 评论 -
常见位运算的lowbit操作
lowbit的实现lowbit(x)可以算出x二进制形式的从左往右的最后一个1与后面的数字组成的数对应的十进制形式举例十进制12=1100,则lowbit(12)=100=8代码实现int lowbit(int x) { return x & -x;//x&-x相当于x&(x按位取反+1)}具体问题二进制中1的个数给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。可以通过lowbit函数得到最后一个1和后面的0组成的数,将原创 2021-04-29 13:18:42 · 375 阅读 · 1 评论 -
前缀和与差分算法
前缀和问题背景:输入一个长度为 n 的整数序列。接下来再输入 m 个询问,每个询问输入一对 l,r。对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。朴素做法:对于每一次查询,都进行累加操作,即用for循环求出A[l]+…+A[r]的值,复杂度为O(n)O(n)O(n)前缀和做法:对原数组进行预处理,假设原数组为A[1…n],则可用递推式A[i] = A[i-1] + A[i]得出新的数组A,易知A[i]保存的是从数组下标1到i的元素的和,则A[l]+…+A[r]的值即为A[r原创 2021-04-28 11:02:36 · 236 阅读 · 0 评论 -
剑指 Offer 63. 股票的最大利润
原题链接题目要求假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?示例 1:输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。示例 2:输入: [7,6,4,3,1]输出: 0解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。思路遍历数组,记录当原创 2021-04-26 23:04:22 · 88 阅读 · 0 评论 -
对快速排序进行尾递归优化
尾递归若函数在尾位置调用自身(或是一个尾调用本身的其他函数等等),则称这种情况为尾递归。尾递归也是递归的一种特殊情形。尾递归是一种特殊的尾调用,即在尾部直接调用自身的递归函数。函数自身调用次数过多会导致递归层数很深,导致爆栈。举个例子:def recsum(x): if x == 1: return x else: return x + recsum(x - 1)当调用recsum(5)时,栈调用如下:recsum(5)5 + recsum(4)5 + (4 +原创 2021-04-26 16:29:35 · 1266 阅读 · 0 评论 -
dfs递归实现数字排列枚举
dfs递归实现数字排列枚举一:递归实现指数型枚举从 1∼n这 n 个整数中随机选取任意多个,输出所有可能的选择方案。输入样例:3输出样例:322 311 31 21 2 3思路对于每个数字,都有两种可能:选取/不选取,因此对于n个数字,有2^n中组合可能n表示枚举对象是1~n递归边界是x==n+1,或者x>n,当已经递归到第n+1曾的时候,说明到达递归边界,此时输出st数组是一个bool数组,st[i]==0表示不选该数,st[i]==1表示选该数#inclu原创 2021-04-17 20:05:57 · 361 阅读 · 0 评论 -
三分钟学会快速排序(图示讲解,附代码,通俗易懂)
三分钟学会快速排序(图示讲解通俗易懂,附简洁代码)文章目录三分钟学会快速排序(图示讲解通俗易懂,附简洁代码)@[toc]tag:分治、排序快速排序的通俗解释对上述图示与代码的解释算法复杂度分析平均时间复杂度:O(nlogn)O(n\log n)O(nlogn)最差时间复杂度:O(n2)O(n^{2})O(n2)c++代码运行截图tag:分治、排序快速排序的通俗解释1.从数组中选出一个元素xxx(可以随意选取)2.把所有<=x<=x<=x的元素放在x前面(形成一个子区间),所原创 2021-02-08 22:39:29 · 9690 阅读 · 4 评论