基础算法
文章平均质量分 67
一星伴月
在沉默中努力,让成功自己发声
展开
-
图的遍历(BFS和DFS)c语言纯手写
考研ing,以防考试限制使用STL等工具,c语言纯手写图和队列/*注意:1、顶点编号与邻接点下标都是从0开始2、代码没有设置容错处理,请确保输入数据无误*/#include <stdio.h>#include<stdlib.h>typedef enum {false,true} bool;#define ERROR -1/* 最大顶点数 */#define MaxVertexNum 10/* 邻接点的定义 */typedef struct AdjVNo原创 2021-09-09 21:18:11 · 363 阅读 · 0 评论 -
最容易理解的KMP算法讲解
对于字符串的匹配问题,我们最先想到的肯定是BF(Brute Force)暴力算法BF算法的思路就是:遍历模板串,判断模板串的当前字符是否与子串的第一个子串相等,如果相等的话,那么子串和模板串同时往后移动一位再次进行判断,当全部相同(子串匹配成功)或者匹配的某一个字符不相同,那么结束匹配。匹配成功或者某一个字符不相同,我们需要将子串复原,模板串后移一位,我们则判断模板串的下一个字符与子串的首字符是否相等,相等再继续往后判断,不相等则模板串往后移动一位。以落谷题目给出的样例为例:ABABABC (模板串原创 2020-09-20 18:52:05 · 200 阅读 · 0 评论 -
next_permutation全排列函数
首先这个函数的位于头文件< algorithm >next_permutation()是按照字典序产生排列的,并且是从数组中当前的字典序开始依次增大直至到最大字典序参考链接因此,这个函数的使用方法只适用于有序的数组力扣题目为例:第K个排序class Solution {public: string getPermutation(int n, int k) { if(!n) return ""; vector<char> ch;原创 2020-09-08 13:12:35 · 132 阅读 · 0 评论 -
696. 计数二进制子串
这题属于一看就会,一做就废的字符串的长度是5w,因此我们需要线性或者nlogn的时间复杂度,偏偏我在最开始的时候用了n^2的方法,直接RE…正常来说肯定是把每一个点作为起点,往后查找,但是这么就RE了(V-V)这里推荐一种比较好的思路:我们可以统计出每段0(1)的长度,然后累加相邻长度最小的即可。以题目的示例1为例得到每段的长度序列:[2,2,2,2]那么,结果就是2+2+2=6再看一组数据"00100":[2,1,2]那么,结果就是:1+1=2相邻两段的最小长度是多少,就能够组合成多少.原创 2020-08-10 11:53:08 · 141 阅读 · 0 评论 -
力扣初级算法(数组篇)
个人觉得这个模块还是很不错的,适合像我一样初学算法的童鞋入门,我一般使用c++做题的(c和java也会 )下面会简单介绍一下我的对每个题目的想法,之后可能会录制讲解视频放到B站供童鞋们参考!删除排序数组中的重复项给出一个升序数组,用O(1)的空间复杂度实现求得数组去重后数组,数组去重的话时间复杂度比较高,代价太大,因此需要换一种思考方向,那么我们可以从前往后覆盖这个数组,看下面的例子:给定 nums = [0,0,1,1,1,2,2,3,3,4]首先我们需要设定一个变量用来记录去重后数组的长原创 2020-08-10 11:34:39 · 671 阅读 · 0 评论 -
二分函数模板
裸二分函数模板,是力扣的一道题就是需要注意一下边界问题就行,不然容易死循环二分查找题目链接下面代码实现的是返回target出现的第一个位置,若没找到则返回-1class Solution {public: int search(vector<int>& nums, int target) { int l=0,r=nums.size()-1; while(l<r) { int mid=l+r&g原创 2020-06-27 19:33:18 · 198 阅读 · 0 评论 -
八数码
求最短路径,bfs可以解决看题目的意思就是给出一个3*3的矩阵,要求通过x的位置变化,然后让矩阵变的有序,即下面的矩阵1 2 34 5 67 8 x如果能够得到上面的矩阵,则输出x移动最少的次数,如果不能得到那么就输出-1对于这个问题的话我们可以把矩阵变成一个长度为9的字符串,然后bfs,每次都得找到x的位置,然后再转化成坐标(x,y)来进行判断上、下、左、右四个方向,哪个方向可以走(肯定是不能超出3*3矩阵的范围),然后再判断一下新的状态是否到达过,如果没有,那么到达这个新的状态x移动次.原创 2020-06-27 19:09:17 · 352 阅读 · 0 评论 -
树与图的广度优先遍历
板子题所有边的长度都相同的话就可以用bfs求最短路径,图的存储的话使用邻接表,因为数据太大的话使用邻接矩阵会爆。链式前向星实现邻接表。链式前向星实现:设置三个数组,一个数组h用来存节点,一个数组e用来存值,一个数组ne用来存下一个节点。我们需要设置索引idx来实现ne的查找,不然没法链接起来void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++;}这个可以看成多个带头结点的单链表,h表示单链表个数,h[i]存的实际是索引idx,ne代原创 2020-06-27 11:04:18 · 193 阅读 · 0 评论 -
数独(通俗易懂)
通俗易懂的方法就是dfs简单爆搜,本文介绍的是最简单粗暴的方法,直接暴力搜索,没有进行任何优化。数独又称为9宫格(如下图所示)每一行的数字都不能重复每一列的数字都不能重复每一个小9宫格(方阵)数字都不能重复可以看做上面三个分别是一个包含1-9的集合因此我们可以设置三个二维数组来记录每一行、每一列、每一个方阵1-9的数字,从而确定每个点可以填哪些数。一维分别表示第几行、第几列、第几个方阵,然后二维用来记录哪些数字已经存在,1表示存在,0表示不存在。假定我们输入的数据如下:8 0 0 0原创 2020-06-26 12:24:04 · 2111 阅读 · 6 评论 -
回文串(两种方法)
回文串:一串正着读和反着读都是一样的一种特殊字符串例如:level、abba 这两个字符串就被称为回文串判断回文串,我推荐两种方法:反转比较法和中分比较法(名称是自己起的哈,有些丑陋)一、反转比较法对于c++的同学这个就十分简单了我们输入的字符串类型定位string型,然后使用reverse函数就可以,然后我们直接比较str1与str2是否相等,相等的话那么就表示输入的字符串为回文串。reverse(str2.begin(), str2.end());当然,输入char、int数组也是原创 2020-06-11 17:36:56 · 8162 阅读 · 0 评论 -
单调栈模板
单调栈顾名思义就是栈里的元素是单调的。但是这个怎么使用呢?怎么就能是单调的呢?看下面的例题题目给定一个长度为N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出-1。输入样例:53 4 2 7 5输出样例:-1 3 -1 2 2题目意思很容易理解那么我们先来看暴力做法,每次取一个数,与前面的数比较for(int i=0;i<n;i++){ for(int j=1;j=i;j++) { if(a[j]>=a[j-1]) { break;原创 2020-06-09 09:27:16 · 248 阅读 · 1 评论 -
前缀和模板
前缀和:用来快速求区间的和输入一个长度为n的整数序列。接下来再输入m个询问,每个询问输入一对l, r。对于每个询问,输出原序列中从第l个数到第r个数的和。1≤l≤r≤n,1≤n,m≤100000,−1000≤数列中元素的值≤1000我们如果每次都把l到r区间的数加起来,那么在数据最大的情况下,时间复杂度就达到了O(1e10+),这样我们显然是不能接受的这时候就用到的前缀和思想我们定义一个数组a用来存放输入的元素,然后再定义一个数组存放前i个元素的和(包括第i个元素),那么,如果我们求l到原创 2020-05-24 10:27:35 · 210 阅读 · 0 评论 -
二分模板
模板题目二分的话就是要注意边界问题!!!对于这个题目的话我们取左边界的话mid=(l+r)/2当a[mid]>=x,那么我们就继续往左边界走,[l,mid]当a[mid]<x,那么我们判断右半部分,[mid+1,r];结束条件就是l与r重合取右边界的话mid=(l+r+1)/2当a[mid]<=x,那么我们就继续往右边界走,[mid,r]当a[mid]>x,那么我们判断左半部分,[l,mid-1];结束条件就是l与r重合为什么取左边界就是(l+r),右边界就是原创 2020-05-15 11:14:07 · 138 阅读 · 0 评论 -
高精模板
以下给出的仅仅是模板哈~没有进行压位,加法和减法都大数,乘法是一个大数乘一个整数,除法是大数除以一个非零整数,只有加法没有处理前导零,模板假定输入符合正常输入。思路的话就是vector逆序存数据,设置一个变量表示进位A+B#include<iostream>#include<string>#include<vector>using namespace std;vector<int> a,b;vector<int> add(vect原创 2020-05-15 10:48:56 · 284 阅读 · 0 评论 -
快速排序
荒废了好多天,终于又要开始学习了~sort谁换不会用,是吧! 接下来的几天,记录一下基础算法的实现与个人想法快速排序题目快排的思路:第一步: 找一个数tmp。一般都是找数组中间位置那个值,平时也可能见到取左边界、右边界,再有就是随机取值。第二步: 然后把数组中的所有数字按这个数字分成两部分 (从小到大排序(升序)为例) 左面就是小于等于tmp的数,右面就是大于等于tmp的数(为什么与tmp等值的元素既可以出现在左半部分,又可以出现在有半部分呢,这个就是快排的精髓了,后面解释)第三步: 划分成原创 2020-05-13 18:50:47 · 168 阅读 · 0 评论