自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 图论导引 - 第四章 树 - 第一节:树的性质和生成树 - 1205

在本章中,我们总体研究树,特别提及连通图中的生成树以及 Cayley 在标记树计数方面的著名成果。森林是不含圈的图,连通的森林就是树。注意,树和森林都是简单图。生成树:给定任意一个连通图GGG,一棵连接GGG所有顶点的树被称作GGG​ 的生成树(spanning tree)。包含所有顶点:生成树包含原图中的所有顶点。树结构:生成树是一个树,这意味着它是连通的(任意两个顶点之间都有一条路径)且没有环(没有回路)。**生成森林:**生成森林是由若干棵生成树组成的,它包含了非连通图GG。

2024-12-05 21:11:38 1390

原创 图论导引 - 第三章 第四节 - 11/13

在中国数学家管梅谷所探讨的这个问题中,一名邮递员希望投递信件,要覆盖尽可能短的总路程并返回其起点。显然,他必须至少遍历其路线中的每条道路一次,且应避免过多道路被重复经过。在这个问题中,一名旅行推销员希望走访若干给定的城市并返回其起点,且要覆盖尽可能短的总路程。走访给定城市可以视为走访图中尽可能多的顶点,即找哈密顿圈。

2024-11-13 21:45:50 1077

原创 图论导引 - 第三章 第三节:哈密顿图 - 11/11

欧拉图:给定的连通图GGG是否存在一条包含其每一条边的闭迹。哈密顿图(Hamiltonian graph):图中存在一条闭迹恰好一次经过GGG的每一个顶点。这样的迹一定是一个圈,除了当GGG是图N1N_1N1​(只有 1 个顶点的零图)时。这样的圈是一个哈密顿圈(Hamiltonian cycle),而GGG​ 是一个哈密顿图。半哈密顿图:如果一个非哈密顿图GGG存在一条经过每一个顶点的路径,那么GGG是半哈密顿图。不一定封闭!

2024-11-11 17:25:14 1653

原创 图论导引 - 第三章 第二节:欧拉图 - 11/10

如果存在一条包含图GGG中每一条边的封闭的迹trail,则连通图GGG是欧拉图。这样的迹是一条欧拉迹(Eulerian Trail)。注意,这个定义要求每条边恰好被遍历一次。回顾:迹要求所有边都不同。且迹是封闭的!即从一个顶点出发,沿着边行走,最终回到起始顶点,且每条边恰好经过一次。如果一个图不是欧拉图,但存在一条迹包含图GGG的每一条边,该图GGG是半欧拉图(semi-Eulerian)。半欧拉图的迹不一定是封闭的!即不要求回到起始顶点。注:半欧拉图中的迹也可以叫欧拉路径。

2024-11-10 15:53:23 1699

原创 图论导引 - 第三章 第一节:连通性 - 11/09

第三章(Paths and cycles)主要讲述了路径和循环相关的图论知识,包括四个部分:连通性、欧拉图、哈密顿图、一些相关算法应用。

2024-11-09 16:40:24 1421

原创 图论导引 - 第二章 - 11/08

一个简单图GGG由一个非空有限集VGV(G)VG以及一个有限集EGE(G)EG组成。我们称VGV(G)VG为GGG的顶点集,EGE(G)EG为GGG的边集。VGV(G)VG中的元素称为顶点 vertices(或节点 nodes)EGE(G)EG是由VGV(G)VG​ 中不同元素的不同无序对组成**(注意:一定是不同元素、不同无序对,与一般图进行区分)**,这些无序对称为边 edges。不同元素 指 不能有“环”,即边不能指向自己。

2024-11-08 17:17:10 1094

原创 图论导引 - 目录、引言、第一章 - 11/05

学习图论的前提:具备基本的初等集合论、矩阵论知识,了解抽象代数知识。本书可以分为四部分:第 1 ~ 4 章节:基础部分,包括图的定义和示例、连通性、欧拉路径和哈密顿路径等。第 5 ~ 6 章:关于平面性和着色的内容,特别提及了四色定理。第 7 ~ 8 章:有向图理论和横截理论,应用于关键路径分析、马尔可夫链、网络流第 9 章:拟阵,联系前面章节,并介绍最新的发展图、点、边、度顶点 vertices边 edge图 graph一个图是一组顶点以及顶点如何连接的表示。任何度量属性都是无关紧要的。

2024-11-05 22:09:57 1230

原创 代码随想录DAY25 - 回溯算法 - 08/24

这道题可以在整数数组中找子集的基础上进行调整,我们可以先找出子集大小大于等于 2 的所有子集,若子集满足非递减序列,则插入结果中。和之前的去重操作类似,我们需要在树层去重,而不是树枝去重,即在同一层 for 循环中进行去重,而不是对递归去重。而本题中数组的元素范围是[-100,100],范围并不大,因此可以用数组直接做哈希映射,效率会提高。输入:nums = [4,6,7,7] 输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]

2024-08-25 14:21:17 1959

原创 代码随想录DAY24 - 回溯算法 - 08/23

方法二的思路都是对树层去重(即在同一层 for 循环中去重),实现方法有两种,分别使用集合 set 或使用数组 isUsed 来辨别重复的元素是在树层中还是在树枝中,如果是在树层中,则去重。先确定组合的第一个回文串,之后再递归从剩余的字符串中分割回文串,将分割好的回文串插入组合中,若组合已经填满(即字符串遍历完),则回溯到上一层重新分割字符串。如果当前元素和前一个元素相同,且前一个元素没有被使用,说明当前元素和前一个元素不在递归中,而是在同一层 for 循环中,即在树层而非树枝,需要去重,跳过。

2024-08-25 11:42:48 945

原创 代码随想录DAY23 - 回溯算法 - 08/22

但和之前不同的是,我们递归寻找下一个元素时还可以是自身,因为可以重复,因为递归时候传入的起始位置仍为 i,即 backTracking(target, sum, candidates, i),而不是 i+1。之前在做组合题目时,每用一个数字,下一个组合就不能用之前用过的,但在这道题里,每考虑一个新组合时本身这个数字能再次使用,这就是在原组合题目的基础上要修改的地方。本题和上一题不一样的地方就在于数组 candidates 中可能包含重复的数字,而且每个数字在一次组合中只能使用一次,不可以多次使用。

2024-08-22 21:54:23 867

原创 代码随想录DAY22 - 回溯算法 - 08/21

回溯是一种类似枚举的搜索方法,回溯和递归相辅相成。

2024-08-22 21:36:59 910

原创 代码随想录DAY21 - 二叉树 - 08/20

每次都从根节点序列中取出根节点,令根节点的左孩子 = 左子树区间中点,根节点的右孩子 = 右子树区间的中点,再将根节点的左右孩子插入节点队列中,如此循环。前序遍历,先判断根节点是否在 [low, high] 的范围内,如果不是则删除,并从左右子树中找到新的根节点;的顺序遍历二叉树,二叉树的最右节点肯定是二叉树的最大值,没有比他更大的,该节点作为起点,之后再遍历中间节点、左子树。返回值是修建过的新子树的根节点。参数即传入的序列数组,返回值是根据序列构建好的二叉树的根节点,需要将返回值传递给上层父节点。

2024-08-20 17:45:37 795

原创 代码随想录DAY20 - 二叉树 - 08/19

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。如果 p = 当前结点 或 q = 当前结点,由于二叉搜索树有序,则另一个结点肯定在子树中,当前结点即为最近公共祖先,直接返回。采用前序遍历,先比较当前结点是否为被删除结点,如果当前结点 < 删除结点,遍历右子树;,为了保持二叉搜索树的特性,这个根节点可以是左子树的最右结点(即左子树的最大值)或右子树的最左结点(即右子树的最小值)。参数是传入的当前结点,要查询的 p、q 结点;

2024-08-19 20:38:17 1036

原创 代码随想录DAY18 - 二叉树 - 08/17

遇到在二叉搜索树上求最值、求差值问题,其实都可以先把二叉搜索树转化为一个有序数组,在有序数组上求解问题会变得简单很多。另一种方法是在中序遍历的过程中使用双指针法,即在递归遍历中用一个指针 cur 指向当前结点,用一个指针 pre 指向上一个遍历过的结点。

2024-08-18 22:49:46 2059

原创 代码随想录DAY17 - 二叉树 - 08/16

递归顺序:采用中序遍历,先判断左子树是否为二叉搜索树,在递归左子树的过程中不断更新左子树的最大值 maxValue,左子树遍历完回到中间结点时,要保证中间结点比左子树的最大值还要大,并更新最大值 maxValue 为中间节点值;执行完上一步判断,才执行 root1 孩子为空而 root2 孩子非空的情况,因为我们是用 root1 存储合并后的树,root1 缺少的需要 root2 进行补齐,而 root2 缺少的不需要理会。返回值是当前树的根节点。否则,不为 null 的节点将直接作为新二叉树的节点。

2024-08-17 23:13:07 924

原创 代码随想录DAY16 - 二叉树 - 08/15

之后先递归遍历左子树找叶子结点,再递归遍历右子树,因为同一层可能有多个叶子节点,但是我们要优先找到最左边的,所以每次都先遍历左子树,这样后续右子树如果也有相同最大深度的结点,就不会覆盖掉之前最左边的结点。采用前序遍历,当遍历到叶子结点时表示采集到一条路径,在遍历的过程中不断更新路径和,到达叶子结点时,比较路径和与目标和是否相同,如果相同可以直接返回 true,如果不相同则要回溯到父节点换另一条路径。,再遍历左子树继续向下寻找路径,遍历完左子树如果没有找到符合的路径,则继续遍历右子树找另外的路径。

2024-08-16 17:37:10 1079

原创 代码随想录DAY15 - 二叉树 - 08/14

按照前序遍历的顺序,我们先遍历该节点的左子树,后遍历右子树,当左、右子树的路径找完以后表示当前结点的所有路径都找完了,需要回溯到上一个结点,此时就可以在路径中弹出该结点,以重新开始新路径。我们可以先遍历左右孩子,返回给父节点后,父节点再根据左右孩子的高度情况 + 1,即加上自身的高度,这样层层返回到根节点就可以知道整个二叉树的高度,也可以知道每个结点的高度。递归顺序:根据 “左右中” 的顺序,先收集结点左子树的路径,再收集右子树的路径,最后才将当前结点插入到左右子树的路径中,更新路径。

2024-08-15 21:55:08 819

原创 代码随想录DAY14 - 二叉树 - 08/13

假设先反转了左子树,接着反转中间的根节点,此时左右子树已经被反转了,之后的右子树其实变成了以前的左子树,后续如果反转右子树,相当于把之前的左子树又反转了回来,那么之前的左子树就被反转了两次。用两个指针 leftNode 和 rightNode 分别遍历左、右子树,用一个队列来存储每一层的结点,但存储的结点顺序并不是从左到右,而是头尾两两存储,(即同侧的两个结点会相邻存储在队列中),故每次对比同侧的结点时都是成对地从队列中取出结点比较。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

2024-08-14 21:42:30 2101

原创 代码随想录DAY13 - 二叉树 - 08/12(深度优先遍历)

所以当遍历到的结点不是最左边的结点时,我们需要暂存到栈里。因为前序遍历中要处理的节点和遍历的节点相同,此时就可以用栈先按 “右左中” 顺序存储结点,(输出是“中左右”,插入时需要反过来),我们只需要按照栈中的结点顺序遍历元素并插入序列数组即可。后序遍历是左右中,逆序是中右左,我们已经知道前序遍历的写法,其实只需要将前序遍历的代码修改为中右左的顺序遍历,最后再将数组翻转就可以得到左右中的后序遍历序列。前序遍历:根据中左右的顺序遍历,遍历到的结点就是要处理的结点,当前节点的右子树结点需要被暂存起来。

2024-08-13 22:34:13 847

原创 代码随想录DAY13 - 二叉树 - 08/12 (层序遍历)

不能用 int 表示每一层的节点值总和,因为一个节点值最大可能是 2^31-1,当多个这么大的节点值相加,总和肯定超过 int 的最大表示范围了。对称二叉树、二叉树的最大深度、二叉树的最小深度、完全二叉树的节点个数、平衡二叉树、二叉树的所有路径、左叶子之和、找树左下角的值、路径总和。这道题目是要按层存储节点值,即同一层的节点值在同一个数组中,并且再用一个数组存储不同的层,也就是返回二维数组。注意:前中后序指的是中间结点的遍历顺序,前序即中间结点最前,中序即中间结点居中,后序即中间节点最后。

2024-08-13 19:31:46 729

原创 代码随想录DAY12 - 栈与队列 - 08/11

之前说过,STL提供的容器适配器有栈 stack、队列 queue,还有第三种优先级队列 priority_queue。优先级队列和队列的区别在于,优先级队列会让优先级更高的先出队,而不是先入队的先出队。每当有新元素进入,优先级队列都会根据排序规则找到优先级最高的元素并将其移动到队头,以保证每次从队头弹出的都是优先级最高的元素。例如,排序规则为降序排列时,优先级队列都会让最大的元素移动到队头,以保证队列是降序排列的。优先级队列的底层实现就是堆,可以自定义是大顶堆或小顶堆。优先级队列默认使用降序排列。

2024-08-11 18:27:58 922

原创 代码随想录DAY11 - 栈和队列 - 08/10

同时为了找到每次窗口的最大值,可以让元素从大到小排列在队列中,最大值即队头元素,但是我们滑动窗口时还需要把窗口要移除的元素弹出,那如何在排过序的队列中找到这个要移除的元素呢?根据 逆波兰表示法,求该表达式的值。遍历字符串,遇到数字,则将数字字符串转化为整数压入栈,遇到运算符则取出栈顶两个数字进行计算,并将中间结果压入栈中,遍历完字符串,栈中最后只剩下一个元素即运算结果。给定一个只包括 ' ( ',' ) ',' { ',' } ',' [ ',' ] ' 的字符串,判断字符串是否有效。

2024-08-10 21:27:23 1086

原创 代码随想录DAY10 - 栈与队列 - 08/09

要将元素放到栈的底层,就得先把原栈里的所有元素弹出,并暂存在另一个栈空间中,再将要插入的元素压入原栈,此后把暂存在另外栈空间中的其他元素压回原栈中。我们需要保持两个队列中的一个队列为空,每次插入新元素时都插入到空队列,这样新元素就可以作为空队列的队头,而剩下的另一个队列中的元素依次弹出插入到新元素的末尾,这样就可以一直保持每次插入的新元素在队头的位置。②当要 pop() 弹栈 或读取队首元素 peek() 时,如果输出栈为空,则把输入栈的所有元素压入输出栈中,再从输出栈弹出元素;③如何判断队列是否为空?

2024-08-10 00:38:03 848

原创 代码随想录DAY09 - 字符串 -08/08

在字符串中。

2024-08-08 23:24:32 760

原创 代码随想录DAY08 - 字符串 - 08/07

因为如果是从前往后遍历,在字符串中每次插入新字符,都需要将之后的元素依次往后移动,时间复杂度会是 O(n^2)。如果是从后往前遍历,可以在插入的同时移动元素,时间复杂度是 O(n)。

2024-08-07 19:17:32 574

原创 代码随想录DAY07 - 哈希表 - 08/06

因为数组是有序的,所以重复的元素会放在一起,则只需要判断 left 指针之后的元素是否和 nums[left] 是重复的,如果是重复的那么就让 left 指针不断移动指向下一个不同的元素,即 left++;昨天做了一道题“两数之和”,用一个 map 存储遍历过的元素,在后续匹配的时候可以直接查找 map ,所以产生了把四数相加拆成两数相加再匹配的想法,即先把每两个数组的元素进行相加求和,再用 map 记录和、和的次数。为了使问题简单化,四个数组具有相同的长度 N,且 0 ≤ N ≤ 500。

2024-08-07 00:56:55 1139

原创 代码随想录DAY06 - 哈希表 - 08/05

哈希表(也叫散列表),Hash Table,即根据关键码的值来直接访问元素的数据结构。数组其实就是哈希表的一种,其中数组索引就是关键码,在数组中我们根据索引下标直接访问到数组元素。哈希表最重要的作用是能快速查询一个元素是否在集合里。

2024-08-06 01:23:27 995

原创 代码随想录DAY05 - 链表总结 - 08/04

链表的定义主要是对节点数据域和指针域的定义,同时要注意构造函数的写法。// 链表节点的定义int val;链表的基础操作:链表的初始化(虚拟头节点)、查找第 n 个节点的元素、头插法、尾插法、删除第 n 个节点的元素、在第 n 个节点前插入元素。

2024-08-04 16:42:59 862

原创 代码随想录DAY04 - 链表 - 8/03

由第(1)个结论可以知道,两个链表如果相交,则他们的末尾结点应该都相同,所以最极端的情况是整个短链表刚好就是长链表的末尾部分,此时会出现相交结点最靠前的位置 sizeA - sizeB。首先 fast 肯定会比 slow 先进入环,而 fast 的速度是每次移动两个结点,slow 的速度是每次移动一个结点,fast 相对于 slow 每次前进( 2 - 1 = 1 )个结点,则进入环以后,fast 肯定会以每次移动一个结点的速度追上 slow。给定一个链表的头节点 head,返回链表开始入环的第一个节点。

2024-08-04 00:26:10 1032

原创 代码随想录DAY03 - 链表 - 08/02

学习了在节点的结构体中定义构造函数,使初始化节点时能直接给变量赋值。C++有默认构造函数,但不会初始化成员变量。int val;// 这样初始化节点时可以直接给变量赋值。

2024-08-02 23:48:51 966

原创 代码随想录DAY02 - 数组 - 08/01

但是题目要求连续子数组,也就是不可以打乱原数组的排序。当 sum < target 时,窗口起点固定为start,需要扩充窗口尺寸,即让 end 继续往前滑动,使窗口内元素的和 sum >= target,此时会不断地跳过 while 循环,执行 for 循环中的 end++。在for的一次循环中,窗口终点固定为 end,如果窗口元素之和 sum >= target,此时以 start 为起点(且以end为终点)的最小子数组长度已被找到,则移动 start 到下一个起点,找到下一个最小数组长度。

2024-08-02 00:27:41 521

原创 代码随想录DAY01 - 数组 - 07/31

只包含需要保留下来的元素的数组,数组下标范围为 [0, slowIndex)。

2024-07-31 23:45:14 775

空空如也

空空如也

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

TA关注的人

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