自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

小胡同的诗

往事已矣,来日犹可追

  • 博客(37)
  • 资源 (1)
  • 收藏
  • 关注

原创 LeetCode442 数组中重复的数据(哈希)

题目链接:leetcode442题面题目大意略解题思路哈希这种问题大致可以分成两类,如果找重复两次的数可以用哈希;如果找不重复的数可以用异或,然后按某个位为 1 开始划分。本题要找重复两次的数,于是可以采用哈希,具体就是使得 nums(i)==inums(i)==inums(i)==i ,这样不重复的数一定归位,而重复的数一定有一个不能归位,那么找出那些不能归位的数即可。代码实现class Solution {public: vector<int> findDupl

2020-09-29 21:11:34 168

原创 LeetCode215 数组中的第K个最大元素(分治 | 快速排序)

题目链接:leetcode215题面题目大意求数组中第k大的数,注意区分第k大和第k小。解题思路暴力每次选取一个当前最大值,重复 K 次即可找到答案时间复杂度 O(nk)O(nk)O(nk),空间复杂度 O(1)O(1)O(1) 。大根堆维护一个大根堆,取前 K 个堆顶元素即可找到答案。时间复杂度 O(n+log2nk)O(n+log_2n^k)O(n+log2​nk),空间复杂度 O(n)O(n)O(n)。分治实际上就是利用快速排序的思想,每次去确定一个数的位置,然后分治

2020-09-29 19:56:56 499

原创 LeetCode793 阶乘函数后K个零(二分+数论)

题目链接:leetcode793题面题目大意f(x)f(x)f(x) 函数是一个求 x!x!x! 结果尾部 0 个数的函数,现在给你一个 K ,让你求能够找到多少个 x 使得 f(x)=Kf(x)=Kf(x)=K 。解题思路首先,我们考虑这个 f(x)f(x)f(x) 函数,不难得出 x!x!x! 尾部 0 的个数等于该数 2 和 5 因子的组数。分别考虑 x!x!x! 的 2 因子和 5 因子的个数取最小值即两个因子的组数,显然,对于 n!n!n! , 5 的因子个数一定小于 2 的因子,

2020-09-28 21:57:22 245

原创 LeetCode81 搜索旋转排序数组 II(二分)

题目链接:leetcode81题面题面大意33 题的延伸,略解题思路二分和 154 优化 153 的一样,当不能确定是左区间还是右区间时,把区间长度减一。数组存在大量重复元素时,时间复杂度退化到 O(n)O(n)O(n)。代码实现class Solution {public: bool search(vector<int>& nums, int target) { if (nums.size() == 0) return false;

2020-09-28 17:53:04 184

原创 LeetCode33 搜索旋转排序数组(二分)

题目链接:leetcode33题面题目大意做法和 153 比较类似,属于二分搜索某个值的问题。解题思路暴力略二分153 那题是夹逼出一个最小值,也就是一定有答案。而本题不同,可能没有这个数,在二分结束的时候需要判定一下是否找到答案。当然,做法类似,都是先确定 mid 所在的位置是在间断点的左边或者是右边,然后再根据各自的区间去划分。注意根据二分的写法对边界情况的判定。代码实现class Solution {public: int search(vector<i

2020-09-28 17:48:13 122

原创 LeetCode154 寻找旋转排序数组中的最小值 II(二分)

题目链接:leetcode154题面题目大意具体题意和 153 那道一样,只不过多了一个元素重复的条件。解题思路暴力略二分做法和 153 一样,只不过对于 mid 和 右端点相等时,我们把区间 - 1 即可。当然,在有大量重复元素的情况下,时间复杂度会退化到 O(n)O(n)O(n)。注意:这两题的右边界 r 都被设为 n - 1 ,这是因为我们知道数组中一定有答案,则如果和正常的二分那样设置在 n 的未知,则最后结束循环的时候 l 可能越界到达 n 。此外,如果初始设置在 n

2020-09-28 17:33:29 124

原创 LeetCode153 寻找旋转排序数组中的最小值(二分)

题目链接:leetcode153题面题目大意题目中的旋转可以理解成整个有序数组循环左移,找旋转点相当于找这个左移的开头,由于原序列有序,相当于找数组的最小值。数组中的元素不重复!解题思路暴力遍历一次数组,寻找最小值。时间复杂度 O(n)O(n)O(n) ,空间复杂度 O(1)O(1)O(1)。二分由于原序列有序,根据左移的特性,我们可以进行二分:如果 mid 的元素值小于等于右端点的元素值,显然旋转点就在 mid 的左边,则此时 r = mid否则旋转点在 mid 的右边,则

2020-09-28 17:17:51 142

原创 LeetCode144 二叉树的前序遍历(Morris遍历 | 非递归栈遍历)

题目链接:leetcode144题面题目大意略解题思路大致方法有递归、利用栈实现非递归以及Morris遍历,对于Morris遍历可以看这篇文章 传送门。其中递归和非递归栈空间复杂度都是 O(log⁡2n)O(\log_2n)O(log2​n) ,Morris 遍历空间复杂度为 O(1)O(1)O(1) 。代码实现Morris 遍历/** * Definition for a binary tree node. * struct TreeNode { * int val;

2020-09-26 23:33:02 245

原创 LeetCode143 重排链表(双指针)

题目链接:leetcode143题面题目大意略解题思路首先用快慢指针找到链表的中点,并分成两个链表,为了方便操作,前面的链表的长度要大于等于后面的链表;接着,把后面的链表逆置,为了方便操作,前面链表的链尾可以暂时称位后面链表的头节点;最后将两个链表归并,由于归并操作要交替插入,于是我们结束的标志是后面链表完全插入到前面的链表的时候算法结束,这也是为什么我们要使得前面的链表元素不小于后面链表的原因。时间复杂度 O(n)O(n)O(n),空间复杂度 O(1)O(1)O(1)。代码实现/**

2020-09-26 22:21:52 117

原创 数据结构 外部排序(败者树、置换-选择排序、最佳归并树)

前言我们知道,计算机在处理数据的时候会先把数据读入内存,然后做相应操作后再写回内存。例如排序,当你内存大小大于数据量的时候,排序所要考虑的时间复杂度仅仅只有在内存中的部分,我们称它为内部排序;相对地,当内存不够,数据量大时,我们就要考虑分阶段进行排序,并且还伴随着大量的 I/O 操作,我们称后者为外部排序。本文主要讲外部排序中的败者树、置换选择排序、最佳归并树的算法原理,至于代码细节不做考虑。原理对于外部排序的顶层设计,我们大致可以归纳为三大步骤:首先,尽可能地读入数据到内存中进行内部排序,之后我

2020-09-26 14:03:35 2646

原创 数据结构 多重邻接表

前言有向图的表示结构有多种,由于其有向性,结构中要人为给它规定起点和终点。对于无向图,我们可以根据有向图的结构,加双向边进行实现,但除了空间翻倍外,在某些要对边进行标记的问题时,还要去找到反向边,有可能这个复杂度不是 O(1)O(1)O(1) 的,那么整体复杂度也会相应提升。于是,多重邻接表可以有效解决这个问题。本文主要介绍多重邻接表的概念、定义等。概念和十字链表类似,多重邻接表是无向图的一种链式存储结构,区别的是多重邻接表:对于结点的设置不再把出边和入边分成两张链表,而是一张链表表示邻边;对于

2020-09-24 00:00:03 498

原创 数据结构 十字链表

前言有向图有多种存储方式:邻接矩阵、邻接表、逆邻接表、十字链表等。本文主要介绍 十字链表 ,并给出其结构体定义以及相应图解。概念十字链表是有向图的一种链式存储结构,可以看成有向图的邻接表和逆邻接表结合出来的产物。他能根据一个结点的出度指针以及入度指针快速找到多条边以及计算结点的出入度。和邻接表类似,结点的结构顺序存储,边的结构链式存储,这样方便边去索引到结点。定义结点结构是一张顺序表,里面每个元素表示图中的一个结点,而指针域中的两个指针分别为出边和入边的弧链表。结点结构(VexNode)

2020-09-23 16:01:11 1529 3

原创 数据结构 广义表

前言顾名思义,广义表就是线性表的拓展。通俗地理解,就是对于之前定义的线性表只能操作本表内的逻辑,而广义表拓宽了这个定义,于是能指向其他广义表,也就是说表与表之间建立起了联系。概念简单地概况广义表:表元素可以是原子也可以是一个广义表地线性表的拓展结构。长度:最上层元素的个数,一个表可以指向其他广义表,此时其他广义表在本表中也抽象成一个元素;指向数据项也就是原子项,此时也为一个元素。深度:其指向其他广义表的最大深度,因为其他广义表还可能再指向另外的广义表,此时求这个拓展的最大深度。注意,这里是最大深

2020-09-23 12:21:17 1262

转载 联合体嵌套结构体的问题

#include <stdio.h>typedef union{unsigned int u;struct{unsigned char a :1;unsigned char b :1;unsigned char c :6;unsigned char d :1;} ST;}UN;int main(){UN.ST.u = 0;UN.ST.a = 1;UN.ST.b = 2;UN.ST.c = 3;UN.ST.d = 4;printf("%d\n", UN.u

2020-09-23 11:33:45 1352

原创 LeetCode 142 环形链表Ⅱ(双指针)

题目链接:leetcode142题面题目大意给你一个链表可能有环,如果有环输出环的入口节点,否则输出 NULL解题思路双指针首先快慢指针进行找环,之后根据滑动窗口寻找入口。我们可以大致证明一下:假设慢指针走的长度为 lalala ,快指针走的长度为 lblblb ,整个链表的节点个数为 sss。那么,整个环的长度可以等于 lb−lalb-lalb−la,非环部分的长度为 s−(lb−la)s-(lb-la)s−(lb−la) ,又因为快指针的长度为慢指针的两倍,即 lb=2lalb=

2020-09-22 23:58:18 670

原创 AOE-网和关键路径算法

前言对于一个工程项目,在管理的时候可以将其按规模、功能等特征划分成不同的模块,而当各个小模块完成并进行整合后整个项目也就相应完成。在划分的方法中,主流的方法是按事件、活动的方式进行划分,并且为了直观表示,可以对应到一张有向图中(一般是DAG图)。对于管理者总是关心各个模块的完成时间节点以及整体模块的完成时间时间节点,这些节点我们对于到图中的点 Vertex ,也成为事件,表示这个时间节点 A 事件完成;对于模块完成所要付出的前置工作我们将其对于到图中的边 Edge,也叫做活动,表示完成事件 A 的前置任

2020-09-22 17:55:06 1654

原创 LeetCode138 复制带随机指针的链表(思维)

题目链接:leetcode138题面题目大意构造一个和原链表一模一样的链表,包括 random 指针。注意的是,操作结束后,原链表的结构不能被破坏。解题思路map根据结构,我们可以先构造出和原链表一模一样的链表,并使每个节点一一对应,这边可以使用一个 map 。然后遍历原链表的所有节点,对于原链表的random 指针我们可以根据查询 map 的内容进行相应的 random 指针修改。时间复杂度 O(nlogn)O(nlogn)O(nlogn),空间复杂度 O(n)O(n)O(n)。把

2020-09-21 18:44:38 114

原创 LeetCode134 加油站(贪心)

题目链接:leetcode题面题目大意gas表示到达 i 位置后能得到的充值cost表示从 i 离开后需要的消费问是否能够从前往后绕一圈回到原点解题思路易错点对于一个起点,即使途中所有的充值和消费大于等于0,但是途中某个位置一旦没油了就会终止。枚举枚举所有起点,暴力检查。时间复杂度 O(n2)O(n^2)O(n2),空间复杂度 O(1)O(1)O(1)。贪心容易想到能绕一圈的前提是所有的所有点的充值和消费求和要大于等于0,在此前提我们去找起点。对于一个合法的起点,我们应该尽

2020-09-21 10:44:57 125

原创 LeetCode 96 不同的二叉搜索树(动态规划 | 递推 | Catalan数)

题目链接:leetcode96题面题目大意求 n 个数字构成的二叉搜索树的种类数量解题思路与本题等价的题目有:凸多边形划分三角形的数量、一串数字通过栈构成的出栈序列数量、2n 长度的 01 串的种类(限制是前缀 1 的数量不少于 0 )等,最终其实可以归结于 Catalan 数的计数问题。以下主要介绍两种动态规划思想的递推,为了方便讲解,问题不妨假设转化为数字的进栈出栈问题:递推我们考虑,对于一串规模为 n 的数字,对于状态 f[i]f[i]f[i] 表示把第 iii 个数字为开头的出栈

2020-09-20 10:13:46 193

原创 LeetCode117.填充每个节点的下一个右侧节点指针 II(思维+dfs)

题目链接:leetcode117题面题目大意给你一个二叉树,树节点指针域中多给了一个next指针,让你在时间复杂度尽可能优的情况下把每层的节点利用next指针串成一个链表。解题思路BFS(二叉树层次遍历)利用队列,额外维护一个树的高度,之后按高度把每层的next指针串连起来。但由于使用到额外的空间,显然不是本题的最优解。时间复杂度:O(n)O(n)O(n),空间复杂度:O(n)O(n)O(n)。DFS+栈我们不难发现,需要处理 next 指针的节点除了整棵树的最右侧链外其余均需要。而

2020-09-19 08:30:03 156

转载 算法复杂度分析中的符号(Θ、Ο、ο、Ω、ω)简介

Θ,读音:theta、西塔;既是上界也是下界(tight),等于的意思。Ο,读音:big-oh、欧米可荣(大写);表示上界(tightness unknown),小于等于的意思。ο,读音:small-oh、欧米可荣(小写);表示上界(not tight),小于的意思。Ω,读音:big omega、欧米伽(大写);表示下界(tightness unknown),大于等于的意思。ω,读音:small omega、欧米伽(小写);表示下界(not tight),大于的意思。大O符号(英语:Big O n

2020-09-17 10:56:38 6698

原创 LeetCode109 有序链表转二叉搜索树(分治 | 双指针)

题目链接:leetcode109题面题目大意给你一个有序数组,让你转成一个平衡的二叉搜索树解题思路乍一看这道题似乎要构造一个 平衡二叉树,而平衡二叉树的实现方法有多种,例如: SplayTree、AVLTree、SBTree、RBTree等。但代码量感人,根据他人思路大致总结如下几种方法:寻找中位数+分治具体思路就是每次对于一个有序链表,取中位数作为根节点,之后左半边和右半边分别递归构造子树。能否满足平衡的限制呢?我们发现左右区间的元素数量最多相差 1 个,显然满足。如何寻找中位数呢?数

2020-09-17 10:08:05 156

原创 二叉树Morris遍历

前言二叉树的遍历方式按顺序划分可分成前序、中序、后序遍历,其中,遍历的时间复杂度为 O(n)O(n)O(n),空间复杂度为 O(logn)O(logn)O(logn)。在部分情况下,例如二叉树退化成链表,空间复杂度为 O(n)O(n)O(n),这是因为无论是递归或者是非递归的遍历方式,都避免不了栈的开销。非递归只不过是把系统的递归栈自己手动实现罢了。Morris 遍历可以在增加时间复杂度的常数,但是实际的时间复杂度仍然是 O(n)O(n)O(n),把空间复杂度优化到 O(1)O(1)O(1),并实现二叉

2020-09-16 14:21:38 211

原创 LeetCode747 至少是其他数字两倍的最大数(树形选择排序 | 锦标赛树)

题目链接:leetcode747题目大意解题思路问题中有说一定存在最大值,意思是这个最大值是唯一的。确定了问题主要是寻找最大值和次大值就可以愉快地解决了,主要思路有如下两种:线性扫描直接 for 一遍即可,如果只是考虑比较的次数,最差会达到 2∗n−22*n-22∗n−2时间复杂度 O(n)O(n)O(n),空间复杂度 O(n)O(n)O(n)锦标赛树这个树是树形选择排序的前置技能,也是堆排序的弱化版,因为空间复杂度较高,但优点是能够减少比较次数。对于本题,仅仅只要寻找最大值和次大值,构造

2020-09-16 02:16:56 171

原创 求顺序表中最大值和次大值的最优算法

问题描述给一个 n 个数字的顺序表,求其中的最大值和次大值。求一个比较次数不大于 n−⌈logn⌉−2n-\lceil logn \rceil-2n−⌈logn⌉−2 的算法。算法顺序比较初始化最大值和次大值是下标为 0 的元素,之后每次更新最大值时,把上次最大值给次大值;不能更新最大值时也要和次大值比较看能否更新次大值。易得最坏情况下比较次数为 2(n−1)2(n-1)2(n−1)。堆我们发现,堆的结构可以在常数时间内找到最大值和次大值。但是在构建堆的时候,每次调整的比较次数约为 2h2h2h

2020-09-16 00:16:11 3529

原创 求顺序表中最大值最小值的最优算法

题目描述给一个 n 个数字的顺序表,求其中的最大值和最小值。求一个比较次数不大于 ⌈3n/2⌉−2\lceil 3n/2 \rceil-2⌈3n/2⌉−2 的算法。思路顺序查找首先最大、最小值初始化为第一个数,对于之后的数我们都进行比较更新。易得最坏情况下比较次数为 2n−32n-32n−3 。实现见代码 f0 部分。分组比较我们可以预处理数组:每两个数字划成一组,较小的放前面,较大的放后面。于是,最小值就可以从前面的数字中获取,最大值从后面的数字获取。比较次数计算如下:复杂度符合要求。实现见

2020-09-15 22:28:41 4501

原创 C++ debug和release版本运行结果不一致浅析

问题最近在写 AVL 树的问题,其中涉及到大量的指针操作。但由于出现了 bug ,在没有修复时出现了单步调试和直接编译运行的结果不一样的情况。大致情况是:单步调试能够根据逻辑把结果运行出来,但是编译运行会出现程序异常中断的情况。问题代码#include<iostream>#include <cmath>using namespace std;template<class K,class V>struct AVLTreeNode{ AVLTreeNode&

2020-09-13 11:25:08 1755

转载 二叉查找树与平衡二叉树

侵删,转自:https://blog.csdn.net/qq_25940921/article/details/82183093 二叉查找树  二叉查找树,也称

2020-09-11 15:06:18 129

原创 LeetCode98验证二叉搜索树(树形遍历 | 中序遍历)

题目链接:leetcode98题目大意给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:节点的左子树只包含小于当前节点的数。节点的右子树只包含大于当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。解题思路树形遍历自行定义一个搜索二叉树的上界和下界,对于一个节点如果在这个上下界之外就不为 BST ,否则就是。对于左子树上界则更新为当且节点的值,对于右子树则把下界更新为当前节点的值。中序遍历利用中序遍历就不用考虑上界的问题,因为遍历的顺序是从左

2020-09-11 12:06:41 178

原创 HDU1007 Quoit Design(分治)

题目链接:hdu1007题目大意给定一个整数 n ,下面跟着 n 对二维坐标 (x, y),其中x、y均为实数,表示平面内的 n 个点。问平面内这 n 个点之间的最短距离是多少?输出这个答案的一半。解题思路枚举时间复杂度 O(n2)O(n^2)O(n2),具体做法略。分治对于分治的做法我们大致可以分为三个步骤:预处理,分离区间,合并区间。首先我们把平面的点一分为二,然后计算各自的最小距离,回溯后取其中最小后并枚举两个区间一个点在左另一个点在右的情况,计算距离看是否能够更新最小值。以下是对

2020-09-11 10:37:39 315

原创 C++nth_element接口使用

前言有这么一类问题,是寻找区间内的第k大或者说第k小(实际上这两个是一个问题),解决算法有排序,权值线段树、主席树、树套树等,但是要么就是复杂度不满意或者不好写。根据快速排序的分治思路,我们还可以在O(n)O(n)O(n)的时间内找到答案,但并不能保证有序,并且STL十分贴心地把这个算法封装到 nth_element 中,本文就是介绍这个接口地使用。原理前言中提到,这个接口的期望复杂度是 O(n)O(n)O(n) ,我们可以假设每次选取的分段标志为最优大致证明一下:T(n)=T(n/2)+n=T(n

2020-09-09 15:36:04 234

原创 LeetCode94 二叉树的中序遍历(栈)

题目链接:leetcode94题目大意给定一个二叉树,返回它的中序 遍历。非递归实现解题思路栈+模拟大致的思路就是不断往左子树切换,直到左边为空后把当前的节点输出,然后转到右子树。如果右子树为空说明需要回溯,弹栈即可。代码实现/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; *

2020-09-04 16:36:10 191

原创 LeetCode86 分隔链表(双指针)

题目链接:leetcode86题目大意给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。示例:输入: head = 1->4->3->2->5->2, x = 3输出: 1->2->2->4->3->5相对位置不变相当于稳定地区分,比如两个相等的数原本的位置划分后不能更改这个相对位置,不同的数更是如此。解题思路双指针可以维护两个链

2020-09-04 16:05:11 145

原创 关于 Android 网络通信开发问题小记

前言对于 Android 应用开发,免不了进行网络通信,其中,大大小小都有涉及到套接字的使用,(Ps:对于通信方面尽量使用 Netty 框架能缩短业务逻辑实现的周期)但使用不当往往会出现各种问题。例如:TCP 的粘包、拆包问题;TCP 连接丢失问题等。但如果经验不够或者涉及到底层的问题该怎么办呢?这时候可以利用抓包去尝试定位问题。当然,对于计算机网络的一些基础问题是前置技能,这里不再概述,本文主要介绍抓包的大致思路。抓包介绍抓包,顾名思义就是获取网络通信的报文。众所周知,一个 PC 想要连接上互联网

2020-09-04 01:24:32 159

原创 LeetCode82 删除排序链表中的重复元素 II(思维)

题目链接:leetcode82题目大意给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。示例一:输入: 1->2->3->3->4->4->5输出: 1->2->5示例二:输入: 1->1->1->2->3输出: 2->3简而言之就是删掉原始序列中,所有出现次数大于1的元素。解题思路直接删除AC 的代码就是这个方法,但逻辑可能略显冗余。先建一个头节点使链表变成带头

2020-09-04 00:42:18 125

原创 LeetCode75 颜色分类(三指针)

题目链接:leetcode75题目大意给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。注意:不能使用代码库中的排序函数来解决这道题。示例:输入: [2,0,2,1,1,0]输出: [0,0,1,1,2,2]进阶:一个直观的解决方案是使用计数排序的两趟扫描算法。首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前

2020-09-02 23:55:45 122

原创 LeetCode73 矩阵置零(思维)

题目链接:leetcode63题目大意给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。示例1:输入:[[1,1,1],[1,0,1],[1,1,1]]输出:[[1,0,1],[0,0,0],[1,0,1]]示例2:输入:[[0,1,2,0],[3,4,5,2],[1,3,1,5]]输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]解题思路1. 暴力模拟遍历 m*n 个点

2020-09-01 23:40:02 150

C语言求职招聘程序小Demo

对于C语言语法的综合应用,其中包括:指针,文件,键盘读入操作等,当中还利用到了数据结构中的链表结构。以及对于程序的说明书以及分析导图。

2019-02-27

空空如也

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

TA关注的人

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