![](https://img-blog.csdnimg.cn/20190918135101160.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
算法和数据结构
文章平均质量分 70
总结各种算法与数据结构在学习过程遇到问题与理解
温逗死
一名假装努力的小学生
展开
-
C/C++深入浅出动态规划
本文主要记录刷题-动态规划相关原创 2021-12-13 10:06:31 · 802 阅读 · 0 评论 -
C++刷题中的贪心算法
贪心算法贪心的本质是选择每一阶段的局部最优,从而达到全局最优。这么说可能比较抽象,举个最简单的例子:桌子上有一堆一包包的糖果,你只能拿10次,如果你想拿最多的糖果,该如何拿呢?肯定要每次都拿到最大包的糖果。贪心套路贪心并未有固定的套路,但是如果题目求最优解时,而你又没有很好的解题办法,就用贪心试一下吧。贪心步骤贪心算法一般分为如下四步:将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解力扣上的题目455.分发饼干题目描述假设你是一位原创 2021-11-27 11:53:56 · 2227 阅读 · 0 评论 -
C/C++刷题中的指针三剑客之“树“
树原创 2021-11-13 11:27:04 · 792 阅读 · 0 评论 -
C/C++妙用数据结构-栈与队列
概述栈和队列,大家应该非常熟悉,队列是先进先出,栈是先进后出。如图所示:具体,栈与队列的实现原理等,大家可以参考我的另一篇文章【STL】stack和queue的实现原理相关题目原创 2021-11-06 10:49:03 · 114 阅读 · 0 评论 -
C/C++ 刷题中头疼的字符串
前言字符串可以看成是字符组成的数组。由于字符串是程序里经常需要处理的数据类型,因此有很多针对字符串处理的题目,以下是一些常见的类型。344.反转字符串题目描述编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。输入输出样例输入:s = ["h","e","l","l","o"]输出:["o","l","l","e","h"]题解这里其实可以用库 reverse原创 2021-10-30 10:41:18 · 277 阅读 · 0 评论 -
C/C++妙用数据结构-哈希表
一、概述哈希表,也称散列表。哈希表是根据关键码的值而直接进行访问的数据结构。哈希表中关键码就是数组的索引下表,然后通过下表直接访问数组中的元素。那么哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里。例如要查询一个名字是否在这所学校里。要枚举的话时间复杂度是O(n),但如果使用哈希表的话, 只需要O(1) 就可以做到。我们只需要初始化把这所学校里学生的名字都存在哈希表里,在查询的时候通过索引直接就可以知道这位同学在不在这所学校里了。将学生姓名映射到哈希表上就涉及到了hash f原创 2021-10-27 10:59:29 · 574 阅读 · 0 评论 -
C/C++刷题中的指针三剑客之“链表“
链表概述什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点是又两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。如图所示:同时,链表又分为单链表,双链表,循环链表等。下面给出链表结点的定义:// 单链表struct ListNode { int val; // 节点上存储的元素 ListNode *next; // 指向下一个节点的指针 ListNode(int x) : val(x),原创 2021-10-24 11:22:21 · 123 阅读 · 0 评论 -
C/C++妙用数据结构-数组
概述数组是存放在连续内存空间上的相同类型数据的集合。vector:动态数组,是我们最常使用的数据结构之一,用于 O(1) 的随机读取。因为大部分算法的时间复杂度都会大于 O(n),因此我们经常新建 vector 来存储各种数据或中间变量。因为在尾部增删的复杂度是 O(1),我们也可以把它当作 stack 来用。array:固定大小的数组,一般在刷题时我们不使用。数组的元素是不能删的,只能覆盖。704.二分查找二分查找的前提是数组一定是有序的,详细可以参考之前写的 C/C++二分查找 。题目描述原创 2021-10-20 11:06:11 · 327 阅读 · 6 评论 -
C/C++神奇的位运算
常用的技巧位运算是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括:“∧”按位异或、“&”按位与、“|”按位或、“∼”取反、“<<”算术左移和“>>”算术右移。以下是一些常见的位运算特性,其中 0s 和 1s 分别表示只由 0 或 1构成的二进制数字。x ^ 0s = x x & 0s = 0 x | 0s = xx ^ 1s = ~x x & 1s = x原创 2021-10-16 10:10:43 · 153 阅读 · 0 评论 -
C/C++刷题中的数学问题(公因数、公倍数、质数等)
公倍数和公因数利用辗转相除法,我们可以很方便地求得两个数的最大公因数(greatest common divisor,gcd);将两个数相乘再除以最大公因数即可得到最小公倍数(least common multiple, lcm)。int gcd(int a, int b) { return b == 0 ? a : gcd(b, a% b);}int lcm(int a, int b) { return a * b / gcd(a, b);}进一步地,我们也可以通过扩展欧几里得算法(ex原创 2021-10-16 09:06:52 · 305 阅读 · 0 评论 -
C/C++化繁为简的分治法
文章目录算法解释241.为运算表达式设计优先级932.漂亮数组312.戳气球算法解释顾名思义,分治问题由“分”(divide)和“治”(conquer)两部分组成,通过把原问题分为子问题,再将子问题进行处理合并,从而实现对原问题的求解。我们在十大排序算法中的归并排序就是典型的分治问题,其中“分”即为把大数组平均分成两个小数组,通过递归实现,最终我们会得到多个长度为 1 的子数组;“治”即为把已经排好序的两个小数组合成为一个排好序的大数组,从长度为 1 的子数组开始,最终合成一个大数组。我们也使用数.原创 2021-10-12 10:29:12 · 168 阅读 · 0 评论 -
C/C++回溯法
回溯法回溯法(backtracking)是优先搜索的一种特殊情况,又称为试探法,常用于需要记录节点状态的深度优先搜索。通常来说,排列、组合、选择类问题使用回溯法比较方便。顾名思义,回溯法的核心是回溯。在搜索到某一节点的时候,如果我们发现目前的节点(及其子节点)并不是需求目标时,我们回退到原来的节点继续搜索,并且把在目前节点修改的状态还原。这样的好处是我们可以始终只对图的总状态进行修改,而非每次遍历时新建一个图来储存状态。在具体的写法上,它与普通的深度优先搜索一样,都有 [修改当前节点状态]→[递归子节点原创 2021-10-06 15:07:35 · 2608 阅读 · 0 评论 -
C/C++基数排序
基数排序基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。算法描述取得数组中的最大数,并取得位数;arr为原始数组,从最低位开始取每个位组成radix数组;对radix进行计数排序(利用计数排序适用于小范围数的特点);动态演示代码实现#include <iostream>#include <vecto原创 2021-10-01 10:49:47 · 655 阅读 · 0 评论 -
C/C++桶排序
桶排序桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。简言之,将值为i的元素放入i号桶,最后依次把桶里的元素倒出来。算法描述设置一个定量的数组当作空桶子。寻访序列,并且把项目一个一个放到对应的桶子去。对每个非空的桶子进行排序。从不是空的桶子里把项目再放回原来的序列中。动态原创 2021-09-30 11:48:22 · 850 阅读 · 0 评论 -
C/C++计数排序
计数排序计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。算法描述找出待排序的数组中最大和最小的元素;统计数组中每个值为i的元素出现的次数,存入数组C的第i项;对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。动态演示代码实现#include <iostrea原创 2021-09-29 11:41:55 · 411 阅读 · 0 评论 -
C/C++二路归并排序
堆排序归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。算法描述把长度为n的输入序列分成两个长度为n/2的子序列;对这两个子序列分别采用归并排序;将两个排序好的子序列合并成一个最终的排序序列。动态演示代码实现#include <iostream>#include原创 2021-09-28 13:43:34 · 510 阅读 · 0 评论 -
C/C++堆排序
堆排序堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。算法描述将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,原创 2021-09-27 12:37:53 · 119 阅读 · 0 评论 -
C/C++希尔排序
希尔排序1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。算法描述先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;按增量序列个数k,对序列进行k 趟排序;每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1时,整个序列作原创 2021-09-26 11:06:55 · 312 阅读 · 0 评论 -
C/C++快速排序
快速排序快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。其中,快排变形比较多,有单路,双路,三路快排等,而且类似变形题也很多,类似找最大K个数等。算法描述快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:从数列中挑出一个元素,称为 “基准”(pivot);重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后原创 2021-09-25 16:17:51 · 852 阅读 · 0 评论 -
C/C++选择排序
选择排序插入排序是一种简单的排序算法,主要思想:首先在未排序的数列中找到最大(小)的元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。算法描述n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:初始状态:无序区为R[1…n],有序区为空;第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1…i-1]和R(i…n)。该趟排序从当前无序区中-选出关键字最小的记原创 2021-09-24 11:26:45 · 329 阅读 · 0 评论 -
C/C++插入排序
插入排序插入排序是一种简单的排序算法,主要思想:对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。算法描述从第一个元素开始,该元素可以认为已经被排序;取出下一个元素,在已经排序的元素序列中从后向前扫描;如果该元素(已排序)大于新元素,将该元素移到下一位置;重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;将新元素插入到该位置后;重复步骤2~5。动态演示代码实现#include <iostream>#include <vector>原创 2021-09-24 11:12:42 · 130 阅读 · 0 评论 -
C/C++优先搜索
文章目录算法解释深度优先搜索695.岛屿的最大面积(medium)547.省份数量(Medium)回溯法广度优先搜索算法解释深度优先搜索和广度优先搜索是两种常见的优先搜索算法,广泛应用于图和树等结构中搜索。深度优先搜索深度优先搜索(depth-first seach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;因此遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。对于树结构而言,由于总是对新节点调用遍历,因此看起来是向着“深”的方向前进。深度优先搜索也可以用来检测环路:.原创 2021-09-24 10:39:48 · 178 阅读 · 0 评论 -
C/C++十大排序算法
文章目录常见的排序算法比较类排序冒泡排序快速排序简单插入排序希尔排序简单选择排序堆排序二路归并排序多路归并排序非比较类排序计数排序桶排序基数排序快速排序类型题215.数组中的第K个最大元素桶排序类型题347.前K个高频元素常见的排序算法在C++中,可以通过std::sort()进行排序,熟悉排序算法主要锻炼自己编程能力,加深自己对算法的理解。算法时间复杂度:比较类排序通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。冒泡排序快速排.原创 2021-09-22 11:38:33 · 191 阅读 · 0 评论 -
C/C++冒泡排序
冒泡排序冒泡排序是一种简单的排序算法,主要思想:重复遍历需要排序额的数列,类似“冒泡”一样,逐渐的将元素浮到数列顶端。算法描述比较相邻的元素。如果第一个比第二个大,就交换它们两个;对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;针对所有的元素重复以上的步骤,除了最后一个;重复步骤1~3,直到排序完成。动态演示代码实现#include <iostream>#include <vector>#include <原创 2021-09-22 11:03:54 · 171 阅读 · 0 评论 -
C/C++二分查找
文章目录算法解释求开方查找区间旋转数组查找数字总结算法解释二分查找也常被称为二分法或者折半查找,每次查找时通过将待查找区间分成两部分并只取一部分继续查找,将查找的复杂度大大减少。对于一个长度为 O(n) 的数组,二分查找的时间复杂度为 O(log n)。举例来说,给定一个排好序的数组 {3,4,5,6,7},我们希望查找 4 在不在这个数组内。第一次折半时考虑中位数 5,因为 5 大于 4, 所以如果 4 存在于这个数组,那么其必定存在于 5 左边这一半。于是我们的查找区间变成了 {3,4,5}。.原创 2021-09-20 13:38:48 · 1027 阅读 · 0 评论 -
C/C++双指针
学习目标:提示:这里可以添加学习目标例如:一周掌握 Java 入门知识学习内容:提示:这里可以添加要学的内容例如:1、 搭建 Java 开发环境2、 掌握 Java 基本语法3、 掌握条件语句4、 掌握循环语句学习时间:提示:这里可以添加计划学习的时间例如:1、 周一至周五晚上 7 点—晚上9点2、 周六上午 9 点-上午 11 点3、 周日下午 3 点-下午 6 点学习产出:提示:这里统计学习计划的总量例如:1、 技术笔记 2 遍2、CSDN 技术博客 3 篇原创 2021-09-18 12:48:15 · 2448 阅读 · 0 评论