![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构
余丰旭
这个作者很懒,什么都没留下…
展开
-
非递归实现树的三种遍历
中序遍历前序遍历后序遍历原创 2021-08-08 17:30:29 · 373 阅读 · 0 评论 -
O(1) 时间插入、删除和获取随机元素
今天做到了这一题O(1) 时间插入、删除和获取随机元素,其利用了哈希的O(1)查找,和数组O(1)的随机访问特点来实现题目所要求的数据结构。并且,做这道题目,纠正了我一个很大的误区,数组的删除,只有在要求顺序不变的情况下,其最坏时间复杂度才是O(N),否则可以通过交换当前数和数组尾部的数字,然后pop_back(),来实现O(1)时间复杂度的删除。/*利用哈希的O(1)查找和数组的随机访问*/class RandomizedSet {private: map<int,int>mp原创 2021-08-04 09:53:31 · 184 阅读 · 0 评论 -
队列模拟栈
栈模拟队列需要两个,而队列模拟栈最少只需要一个。即每次需要出栈时,把队尾元素返回即可(其他元素出队再入队)。下面给出用双队列模拟栈的代码,其中now标记的使用,比较巧妙class MyStack {private: queue<int> qArr[2]; int now=0;public: /** Initialize your data structure here. */ MyStack() { } /** Push e原创 2021-07-29 09:53:09 · 433 阅读 · 0 评论 -
双栈模拟队列
使用第一个栈存储push的元素,只有当需要pop时,才将第二个栈中的元素全部倒入到第二个栈中。n次操作总复杂度为O(n)class MyQueue {private: stack<int> st1,st2; int popSt2(){ int ans=st2.top(); st2.pop(); return ans; } void transfer(){ while(!st1.empty())原创 2021-07-29 09:28:25 · 185 阅读 · 0 评论 -
手动实现一个优先级队列(二叉堆)
手动实现一个优先级队列,拥有插入、弹出、判空功能。核心代码是对维护堆结构的代码:从完全二叉树逆序第一个有子节点的节点开始调整。//手动实现一个二叉堆(优先级队列)#include <iostream>#include <vector>#include <algorithm>using namespace std;class PriorityQueue{public: //插入 void push(int n){ arr.pu原创 2021-07-29 09:11:46 · 109 阅读 · 0 评论 -
单调队列解决滑动窗口最大值问题
今天遇到一道滑动窗口最大值问题239滑动窗口最大值,发现单调队列是解决这类问题的高效方法,遂加以记录。单调队列:即保持单调有序的队列。底层数据结构使用双端队列比较好,C++需要添加<deque>头文件。滑动窗口最大值问题中,我们关心的是滑动窗口内的最大值,当滑动窗口向右移动一位时,需要删除一个元素和添加一个元素。对于添加元素来说比较好办,如果添加的元素大于当前最大值则替换其为最大值。而删除元素,如果删除的是最大值,则需要重新遍历滑动窗口内容,造成效率的低下。研究此问题发现,如下图,当添加的原创 2021-07-28 20:43:29 · 167 阅读 · 0 评论 -
单调栈的应用
单调栈实际上就是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内的元素都保持有序。单调栈模板单调栈一般用来解决一类问题:Next Greater Number。比如说,输入一个数组 nums = [2,1,2,4,3],你返回数组 [4,2,4,-1,-1]。即找到每个元素之后,第一个大于它的元素,如果没有则设置为-1。解决方式:使用一个栈st,然后逆序来看nums数组,先将所有栈中比当前元素小的全部弹出(比当前元素矮的元素都是后续无法利用的无效信息,如图,矮个子会被高个子挡住,因此丢弃),然原创 2021-07-27 21:40:08 · 407 阅读 · 0 评论 -
优先级队列(堆)合并K个升序链表
在做23合并K个升序链表这题时,发现使用优先级队列(堆)能够高效地解决此问题。思路:直接无脑地将所有节点扔进优先级队列中(小根堆),然后依次取出所有节点,按照头插法构建结果链即可。注意:这里C++优先级队列对于自定义数据类型的比大小的实现,是通过一个结构体内实现()运算符重载来实现的。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * L原创 2021-07-27 18:58:02 · 230 阅读 · 0 评论 -
利用双堆找中位数
今天做了一题堆相关的题目295数据流的中位数,题解巧妙地用一个大根堆和一个小根堆来快速计算中位数。其中添加新数字的写法十分精妙:如果一个数字要添加到小根堆,就先添加到大根堆,再将大根堆堆顶的元素转移至小根堆;反之亦然,以此能够保证小根堆中的元素永远大于大根堆中的元素。其中,C++优先级队列底层默认是一个大根堆(使用了less<xxx>,更换成greater<xxx>,即变为小根堆)。class MedianFinder {public: /** initialize原创 2021-07-27 17:33:31 · 346 阅读 · 0 评论 -
最大频率栈
今天写到一到数据结构的题目,觉得很有意思,遂记录下leetcode895最大频率栈。这题既需要记录每个数字的频率,又需要记录每种频率拥有的数字,故采用两个map来实现。执行过程如下:class FreqStack {public: FreqStack() { maxFreq=0; } void push(int val) { /*查询是否已存在*/ if(numFreq.find(val)==numFreq.end(原创 2021-07-27 14:38:57 · 77 阅读 · 0 评论 -
堆与堆排序
堆堆其实就是一种数组形式的完全二叉树,具体分为大根堆和小根堆大根堆:父节点的值大于等于子节点的值小根堆:父节点的值小于等于子节点的值堆排序//写一个堆排序,堆其实就是一个数组形式的完全二叉树#include <iostream>#include <algorithm>using namespace std;//将数组的一部分(0~len-1)转换为一个大根堆void makeHeap(int arr[],int len){ int index=len原创 2021-07-26 21:24:09 · 97 阅读 · 0 评论 -
手动实现LRU缓存结构
LRU:最近最少使用算法。LRU缓存算法,由哈希表和双向链表构成,能以O(1)时间复杂度获取缓存的键值,也能以O(1)的时间复杂度存储键值。Java中有内置类型LinkedHashMap,可以直接用于LRUCache的实现。C++没有,需要手动实现,这里我手动实现一个,并测试其功能。#include <iostream>#include <map>using namespace std;struct Node { int key, val; Node原创 2021-07-19 17:10:47 · 163 阅读 · 0 评论