数据结构
文章平均质量分 80
star_function
这个作者很懒,什么都没留下…
展开
-
Leetcode 常见报错原因之 heap-buffer-overflow on address 和 reference binding to misaligned address
1. SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior对数组进行操作时,一定要注意数组的可索引范围,保证数组不发生越界。在 Leetcode 中数组越界会给出如下几种报错信息:1. AddressSanitizer: heap-buffer-overflow on address报错信息:==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000032原创 2022-01-19 17:14:23 · 17742 阅读 · 0 评论 -
排序之快速排序
快速排序1. 思路2. 实现3. 示例1. 思路快速排序顾名思义就是很快的排序,它的时间复杂度为 O(nlogn),空间复杂度也是 O(nlogn),它是一种不稳定的排序。它为啥比插入排序、选择排序、冒泡排序快呢?因为它可以一次性将主元元素放在合适的位置。主元是什么呢?数组中主元左边的元素都比主元小,主元右边的元素都比主元大。快速排序采用分治的思想,分别对主元左边的数组和主元右边的数组进行排序,直至所有元素都是排好序的。2. 实现首先我们需要找到主元,并将主元放在正确的位置上,使主元左边的原创 2021-10-17 19:28:02 · 149 阅读 · 0 评论 -
LeetCode 之 数组中的第K个最大元素(二)
上一篇文章中,使用冒泡排序和快速排序解题。本文将使用堆排序解题。优先队列实现堆排序class Solution {public: int findKthLargest(vector<int>& nums, int k) { priority_queue<int, vector<int>, greater<int>> minheap; for(int i = 0; i < nums.原创 2021-10-17 11:02:22 · 103 阅读 · 0 评论 -
排序算法之堆排序(二)
堆排序1. 基础知识2. 堆调整函数3. 建堆函数4. 堆排序函数5. 堆排序的应用参考链接1. 基础知识一般使用一个一维数组存储堆,那么如何找到父结点及其对应的子结点呢?如果父结点的下标为 i ,那么左子结点的下标就是 2 * i + 1;如果父结点的下标为 i ,那么右子结点的下标就是 2 * i + 2;如果子结点的下标为 i ,那么父结点的下标就是 (i - 1) / 2 。2. 堆调整函数堆调整函数的功能是使堆调整成大根堆(小根堆),这里以大根堆为例进行说明。即堆结点的值要大于或等原创 2021-10-08 23:40:14 · 236 阅读 · 0 评论 -
排序算法之堆排序(一)
堆排序基础1. 最大堆和最小堆2. 堆的调整函数3. 堆的建立函数4. 代码实现参考链接一般用一维数组来存储用来建堆的元素(完全二叉树),然后根据大根堆(小根堆)的定义对堆进行调整,最后实现堆的建立。1. 最大堆和最小堆大根堆:堆的父结点大于等于它的子结点。堆顶元素为数组的最大值。小根堆:堆的父结点小于等于它的子结点。堆顶元素为数组的最小值。对于任意结点的下标 i ,它的父结点下标为 (i - 1) / 2对于给定的父结点下标 i , 它的左子结点的下标为 2 * i + 1,右子结点的下标为原创 2021-10-08 15:12:43 · 89 阅读 · 0 评论 -
LeetCode 之 数组中的第K个最大元素(一)
数组中的第K个最大元素1. 冒泡排序1.1 从小到大的冒泡排序1.2 从大到小的冒泡排序2. 快速选择排序2.1 快速排序优化2.2 快速选择排序(非递归)2.3 快速选择排序(递归)参考链接题目要求给出数组中第 k 大的元素,我最直接的想法就是对整个数组进行排序,然后返回数组中第 k 大的元素。1. 冒泡排序要想完成对数组 nums 的排序,冒泡排序需要进行 nums.size() - 1 轮排序,因为最后一个元素无需进行排序。冒泡排序每轮排序都会将待排数组中的最大值放到数组的末尾。因此,要想找原创 2021-10-08 00:16:26 · 288 阅读 · 0 评论 -
LeetCode 之 乘积最大子数组
乘积最大子数组1. 暴力遍历2. 动态规划2.1 定义子问题2.2 状态转移方程2.3 返回最值2.4 报错解决3. 空间优化参考链接题目要求找出数组 nums 中乘积最大的连续子数组,最直接的办法是遍历整个数组,穷举以数组元素 nums[i] 为开头的所有连续子数组,通过比较所有连续子数组的乘积,找到最大值,并返回。可是穷举所有子数组的乘积的过程中,存在很多重复计算。因此可以考虑使用动态规划的思想来优化算法。知识点: 动态规划及其空间优化1. 暴力遍历这种方法通过穷举所有可能的结果,得到最大值原创 2021-10-06 23:50:03 · 1112 阅读 · 0 评论 -
LeetCode 之 颜色分类
颜色分类1. 快速排序1.1 思路1.2 实现2. 指针法2.1 单指针2.2 双指针参考链接本题可以用多种方法进行求解。如果将其看作排序问题,排序 0 、1、2,那么可以使用排序算法进行求解。如果将其看成原地调换数组元素位置,那么可以使用指针法进行求解。知识点: 快速排序、快慢指针、循环不变量。1. 快速排序1.1 思路快速排序采用了分治的思想,首先找出一个主元,我们一般取数组的第一个元素作为主元。然后调整数组元素的位置,使得主元左边都是小于主元的元素,主元右边都是大于主元的元素。之后再分别对原创 2021-10-06 12:07:58 · 144 阅读 · 0 评论 -
LeetCode 之 求根节点到叶节点数字之和
求根节点到叶节点数字之和1. 遍历框架2. 思路3. 实现参考链接题目要求计算根节点到所有叶节点的数字之和,因此需要遍历整个二叉树。涉及二叉树的题目一般考虑用递归解决,涉及路径又可以考虑回溯法(DFS)。其实递归和回溯不能完全分开,因为递归中往往包含着回溯。知识点: 递归、回溯法(DFS)1. 遍历框架首先,先来回顾二叉树的遍历框架 ,具体可见我之前的文章 数据结构之树(一)。这里以后序遍历为例,首先需要判断结点是否为空,然后递归左右子树。void PostOrderTraversal(B原创 2021-10-05 16:43:37 · 202 阅读 · 0 评论 -
LeetCode 之 二叉树的层序遍历
二叉树的层序遍历1. 二叉树的层序遍历(102)1.1 队列实现 BFS1.2 层序遍历2. 二叉树的层序遍历 II (107)参考链接二叉树的层序遍历过程和广度优先搜索 BFS 的搜索过程非常相像,因此考虑用 BFS 算法进行解题。深度优先算法(DFS )利用的数据结构是栈,这个栈是系统自己维护的;广度优先算法(BFS)利用的数据结构是队列,这个队列需要我们自己手动维护。1. 二叉树的层序遍历(102)这道题目不仅要求对二叉树进行层序遍历,还要求将得到的结点值分层存储,每一层放在一个小数组里,原创 2021-10-05 09:46:00 · 142 阅读 · 0 评论 -
LeetCode 之 合并有序数组、链表
合并两个有序数组、链表1. 合并两个有序数组1.1 直接排序法1.2 双指针法2. 合并两个有序链表2.1 双指针法(迭代法)2.2 递归法参考链接1. 合并两个有序数组题目要求合并两个数组,并使合并后的数组有序。知识点: vector 容器的使用(创建指定大小的数组,数组的拷贝赋值)、双指针法、归并排序。1.1 直接排序法最直接的方法是:先将两个数组合并到一个数组中,然后对整个数组排序。主要用到了的知识点是 vector 容器的赋值和排序。算法的时间复杂度是 :O((m+n)log(m+n原创 2021-10-04 21:50:49 · 394 阅读 · 0 评论 -
LeetCode 之 二叉树的最近公共祖先
二叉树的最近公共祖先递归求解参考链接这道题目是一道有实际背景的题目,git rebase 就是基于相同的原理查找最近的公共主分支的。由于是二叉树类的题目,所以第一反应是用递归进行求解。首先明确祖先的定义:如果节点 p 在 root 的左、右子树中或 p == root,那么 root 是节点 p 的祖先。递归求解使用递归时,需要明确终止条件,递归函数作用以及返回值。终止条件:当二叉树为空时,返回 NULL;当节点 p 或 q 为 root 时,就返回 root;递归函数的作用:返回当前节原创 2021-10-04 10:32:38 · 108 阅读 · 0 评论 -
Leetcode 之两数之和 与 三数之和
求解两数之和、三数之和1. 两数之和1.1 暴力法1.2 hash表2. 三数之和2.1 双指针法参考链接1. 两数之和求解两数之和是 LeetCode 上的第一道题。题目中有一个值得注意的地方:“数组中同一个元素在答案中不能重复出现”。本文试着用最直接的方法求解,再逐步优化求解过程。知识点:map、unordered_map 的用法(find 和 count 以及 insert),去除重复解。1.1 暴力法拿到题目,第一反应就是通过两次遍历数组,实现暴力求解。遍历整个数组,尝试为每个数组原创 2021-10-04 00:48:28 · 201 阅读 · 0 评论 -
递归倒序输出“hello”
做了一个小练习,倒序输出"hello"。要求用递归实现。分享下我的代码1. 思路说到递归,就是函数自己调用自己。所以定义的函数中一定有调用自己的部分,要不就不是递归了。1.1 函数声明定义递归函数,首先得给函数起个函数名,我这里叫 print_hello。函数还得有返回值和参数,这个函数就是打印字符就行,所以返回值为空。参数的话,肯定得有字符串传入,要不怎么倒序打印字符串呢。2. 实现#include <iostream>#include <cstring>u原创 2021-09-21 23:39:54 · 2329 阅读 · 0 评论 -
LeetCode 之 回文链表
回文链表1. 递归法1.1 思路1.2 代码实现2. 快慢指针法2.1 思路2.2 代码实现2.3 实现细节参考文献回文链表是指链表中的结点值正着读、反着读结果都是一样的链表。题目要求判断一个单链表是否为回文链表。判断回文字符串使用双指针法相对容易,但是由于链表不能直接倒序遍历,所以需要另寻他法。1. 递归法算法的时间和空间复杂度都是 O(N)。1.1 思路由于链表不能直接倒序遍历,所以考虑生成一个原链表的反转链表。之后遍历原链表与反转链表,对比两个链表是否相同。相同即为回文链表,不同则原创 2021-08-29 14:59:32 · 360 阅读 · 0 评论 -
LeetCode 之 反转链表的一部分
反转链表局部1. 递归法1.1 思路1.2 代码实现2. 迭代法2.1 思路2.2 代码实现参考文献反转链表的局部是反转整个链表的进阶题目。同样,也可以采用递归和迭代两种方法解题。递归实现较为简洁,迭代实现需要注意细节。1. 递归法算法时间复杂度为 O(n), 空间复杂度为 O(n)。递归法需要明确基础条件:当 left == 1时,反转区间 [left, right] 中的结点相当于反转前 right 个结点。递归的较小规模问题:reverseBetween(head->next, le原创 2021-08-28 21:23:07 · 794 阅读 · 0 评论 -
LeetCode之反转链表
反转链表1. 递归法1.1 思路1.2 代码实现1.3 实现细节2. 迭代法2.1 思路2.2 代码实现参考文献反转链表是笔试、面试中考察频率较高的算法题目。本文给出两种解题思路,并用C++实现编码。1. 递归法递归写法较为简单,但算法效率不高。算法时间复杂度为 O(n), 空间复杂度为 O(n)。1.1 思路递归是函数调用自身的一个过程,可以将问题转换为较小规模的问题进行求解。使用递归法解题时,注意一定不要陷入细节。毕竟人脑的算力是有限的,不能人工维护多个栈。用递归解题需要考虑以下几点:递原创 2021-08-28 08:10:03 · 262 阅读 · 0 评论 -
排序算法之冒泡
冒泡排序冒泡排序算法的时间复杂度O(n2)最好情况,初始是排好序的,顺序,O(n)最坏,整个数组是逆序,O(n2)从小到大冒泡排序从上到下比较两个相邻的元素,如果顺序正确,保持不变;如果是逆序,则交换两个元素的位置。完成一趟排序,最大的元素处于数组最后的位置。之后对前 N-1 个元素重复上述排序过程。优化:如果在中间某一步,数组已经完成排序,完全有序。在一趟排序中,没有任何一对元素需要交换位置,则说明完全有序,从未调用swap函数。优点:所有待排元素都放在链表中,排序稳定稳定:只有当前元素严原创 2021-08-12 21:18:29 · 2264 阅读 · 0 评论 -
数据结构之树(三)
平衡二叉树1. 什么是平衡二叉树2. 平衡二叉树的调整1. 什么是平衡二叉树首先给出平衡二叉树的定义:平衡二叉树(Balance Binary Tree)(AVL树)的任一结点左、右子树高度差的绝对值不超过1。用平衡因子度量,即 |BF(T)| < = 1。BF(T) = hl - hrhl 、hr 分别为T的左右子树高度。当然,平衡二叉树也可能是空树。给定结点数为 n 的AVL树的最大高度为 O(log2n)。2. 平衡二叉树的调整平衡二叉树删除或者插入结点后,可能变得不平衡,所原创 2021-07-22 20:26:03 · 69 阅读 · 0 评论 -
数据结构之树(二)
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar原创 2021-07-21 20:30:27 · 113 阅读 · 1 评论 -
数据结构之树(一)
二叉树1. 二叉树的存储结构2. 二叉树的三种遍历2.1 先序遍历2.2 中序遍历2.3 后序遍历3. 层序遍历1. 二叉树的存储结构二叉树可以使用顺序存储结构数组进行存储,也可以使用链式存储结构链表进行存储。下面给出LeetCode中二叉链表的结点结构定义代码。/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *ri原创 2021-07-20 21:18:16 · 191 阅读 · 0 评论 -
数据结构之链表
链表1. 定义2. 主要操作2.1 求表长2.2 查找2.3 插入2.4 删除3. LeetCode高频题1. 定义LeetCode 中的链表定义如下。其中, val 为结点对应的数据值,next 为结点结构指针,指示下一个结点的位置。//每一个结点用一个struct表示struct ListNode { int val; ListNode *next; ListNode() : val(0), next(nullptr) {} ListNode(int x)原创 2021-07-19 21:29:03 · 117 阅读 · 0 评论