高级数据结构与刷题
C++高级数据结构与算法
KingOfMyHeart
会好起来的.
展开
-
二叉树的存储之数组存储
示例:如上图所示,将此二叉树存放入数组Array当中,有如下的关系:根结点存放在Array[0]中左孩子存放在Array[2*i+1] (i表示父亲结点在数组中的下标index)右孩子存放在Array[2*i+2] (i表示父亲结点在数组中的下标index)最终数组Array存储的结果如下:另外:也可以将将根节点存放在Array[1]中,左孩子结点存放在Array[2*i]右孩子结点存放在Array[2*i + 1]这样做计算方式比较方便,比如要计算某个结点的父亲结点的下标,原创 2021-11-28 17:08:34 · 3430 阅读 · 0 评论 -
FIFO缓存的设计与代码
缓存基本概念以及常见数据的淘汰机制设计思路队列用来保存缓存的key,保证键值对的顺序 队列的特性可以很好的说明哪个数据是最先进入的(容器第一个元素)哈希表用来保存真正需要缓存的数据key:value代码#include <unordered_map>#include <vector>class FIFOCache{public: FIFOCache(int capacity = 10):capacity_(capacity) { i原创 2021-07-01 23:16:13 · 310 阅读 · 0 评论 -
链表类题目:反转部分链表
题目描述给定一个链表,给定left和right值,要求反转链表中left-right之间的链表题目解析找到left的前继和right的后继,然后将left-right进行反转,然后进行拼接ListNode *ReverseSubLink(ListNode*head,int left,int right){ //头结点可能被修改,那么就创建一个虚拟结点 ListNode * dummy_node = new ListNode(); dummy_node->next =原创 2021-06-29 18:49:29 · 222 阅读 · 0 评论 -
链表类题目:链表反转
题目描述将一个链表反转题目解析双指针迭代ListNode *ReverseLink(ListNode*head){ if(head == nullptr || head->next == nullptr) return head; ListNode *pre = nullptr; ListNode *cur = head; while (cur != nullptr) { ListNode * tmp = cur->nex原创 2021-06-29 18:30:36 · 190 阅读 · 0 评论 -
链表类题目:找到有环链表的入口结点
题目描述判断链表是否有环,找到环的入口结点,如果没有环 返回Null题目解析使用set,如果不在set中,那么加入set中,返回第一个已经在set中的节点。ListNode* LoopEntry(ListNode *head){ if(head == nullptr || head->next==nullptr) return nullptr; std::set<ListNode*> st; ListNode *cur = head;原创 2021-06-29 18:16:38 · 160 阅读 · 1 评论 -
链表类题目:判断链表是否有环
题目描述判断链表是否有环题目解析:使用set,遍历时如果不在set中,则加入set,如果已经在set中,说明之前已经出现过,那么返回true.使用快慢指针:slow每次走一步,fast每次都2步,如果有环一定会相遇,即fast == slowbool hasCycle(ListNode*head){ if(head == nullptr || head->next==nullptr) return false; ListNode * slow = head;原创 2021-06-29 17:29:13 · 114 阅读 · 0 评论 -
链表类题目:删除链表倒数第n个结点
题目描述删除链表中倒数第n个结点,并返回头结点指针题目解析先遍历一遍,获取链表长度length,然后再从头遍历length-n步,获取要删除结点的前继结点,进行删除即可。ListNode *RemoveNthNodeFromLink1(ListNode*head,int n){ if(head == nullptr) return nullptr; ListNode * virtual_node = new ListNode(); virtual_node->n原创 2021-06-29 17:05:42 · 135 阅读 · 0 评论 -
链表类题目:求一个链表的中间结点
题目描述返回链表中间结点的地址题目解析:两边扫描法,先计算链表长度len,然后再去遍历len/2,即可快慢指针法slow指针每次走一步fast每次走两步ListNode *FindMiddleNode(ListNode*head){ ListNode *slow = head; ListNode *fast = head; //奇数 和 偶数情况都需要考虑到 while(fast != nullptr || fast->next != nullpt原创 2021-06-29 14:23:33 · 190 阅读 · 0 评论 -
数组类题目:汇总区间
题目描述给定一个无重复元素有序整数区间数组 arr返回恰好覆盖数组中所有数字的 最小有序 区间范围列表也就是说,arr的每个元素都恰好被某个区间范围锁覆盖,并且不存在属于某个范围但不属于arr的数字x输出格式如下:对于每个子序列[a,b]if a!=b “a->b”if a==b “a”对于数组 0 2 3 4 6 8 9[“0”,“2->4”,“6”,“8->9”]题目解析:std::vector<std::string> SummaryRanges(原创 2021-06-28 20:32:53 · 129 阅读 · 0 评论 -
数组类题目:非递减数列(升序数组)
题目描述:给一个长度为n 的整数数组请你判断在最多改变一个元素的情况下,该数组能否变成一个非递减数列,即升序数列递减数列是这样定义的:对于数组中任意的i(0<= i <= n-2) 总满足nums[i] <= nums[i+1]如:2 2 3 返回true4 2 1 返回false题目解析:思路:利用差值为1的双指针,如果前面小于后面,继续相互迭代,否则修改一次值,至于修改arr[i]还是修改arr[jde 值,需要根据前后数值大小判断,且只能修改一次,当出现修改第二次时原创 2021-06-28 15:51:01 · 312 阅读 · 0 评论 -
数组类题目:旋转数组
题目描述:给定一个数组,将数组中的元素向右移动k个位置 其中k是非负数(循环移动的问题)假设数组:1 2 3 4 5 6 7 ,右移3位后:5 6 7 1 2 3 4题目解析:该题目与字符串的循环移动类似,字符串循环移动先将后面3位进行反转,再将前面的部分进行反转,最终将整个数组反转。void ReverseArray(int *arr,int left,int right){ while(left < right) { int tmp = a原创 2021-06-28 15:16:08 · 136 阅读 · 0 评论 -
数组类题目:判断一个数组是否为有效山脉数组
题目描述给定一个数组,如果他是有效的山脉数组就返回true,否则返回false满足以下2个条件:数组len > = 3在0 < i <arr.len-1的情况下,存在 i使得:arr[0] < arr[1] < …arr[i-1] < arr[i] 左边递增arr[i] > arr[i+1] > … > arr[arr.len-1] 右边递减题目解析:1.利用双指针进行遍历,一个为i,一个为i+1,前面满足arr[i+1] >原创 2021-06-28 14:39:23 · 565 阅读 · 0 评论 -
数组类题目:除自身以外数组的乘积
题目描述:给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。输入: [1,2,3,4]输出: [24,12,8,6]要求:不要使用除法,且在 O(n) 时间复杂度内完成此题。进阶:可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)题目解析:暴力法:不满足时间复杂度要求,即遍历一个数,分别遍历他前面的乘积和后面元素的乘积原创 2021-06-28 09:36:16 · 194 阅读 · 0 评论 -
数组类题目:一维数组求动态和(前缀和)
题目描述:给你一个数组nums,数组的动态和计算公式 runningSum[i] = sun(nums[0],…,nums[i]);返回数组的前缀和数组。题目解析:std::vector<int> RunningSum(int *arr,int len){ std::vector<int> output; output.push_back(arr[0]); for(int i = 1;i<len;++i) { outpu原创 2021-06-28 09:04:37 · 368 阅读 · 0 评论 -
字符串类题目:判断一个字符串是否为回文串
忽略字母的大小写,忽略非字母的字符:bool IsPalindrome(const std::string &str){ if(str.size() < 2) return false; int start = 0; int end = str.size()-1; while(start < end) { //忽略左边无效字符 while (start < end && !isalnum原创 2021-06-27 22:57:15 · 637 阅读 · 0 评论 -
字符串类:反转字符串
void ReverseString(std::string&src){ if(src.size() < 2) return; int start = 0; int end = src.size()-1; while(start < end) { auto t = src[start]; src[start] = src[end]; src[end] = t; start++;原创 2021-06-27 22:38:09 · 106 阅读 · 0 评论 -
数组类题目:删除有序数组中的重复元素2
题目描述:给定一个有序的数组,原地删除重复出现的元素,使得每个元素最多出现2次返回删除后数组的新长度输入:nums = [1,1,1,2,2,3]输出:5, nums = [1,1,2,2,3]题目解析:双指针法:从第三个元素开始,如果arr[i]和arr[j-2]的元素相同,进行赋值。void RemoveDuplicates(int *arr,int len){ if(len <= 2) return; //从第三个元素开始 int j = 2;原创 2021-06-27 22:17:16 · 210 阅读 · 0 评论 -
数组类题目:删除有序数组中的重复元素
题目描述:给定一个有序的数组原地删除重复出现的元素,使得每个元素只出现一次,返回删除后数组的新长度。题目解析:暴力法双指针法:一个快指针一个慢指针,如果快指针指向元素和慢指针指向元素相等,那么快指针++即可如果不相等,慢指针先++,用快指针元素赋值给慢指针元素int RemoveDuplicates(int *arr,int len){ //慢指针 int j = 0; //i为快指针 for(int i = 1; i < len;++i) {原创 2021-06-27 21:29:04 · 215 阅读 · 0 评论 -
字符串类题目:统计字符串中每个字符出现的次数
题目描述给定一个字符串,且每个字符都是小小写,统计每个字符出现的次数。题目解析建立map表,遍历字符数组建立一个字符数组,长度len = 26,因为一共有26个小写字母,且每个下标代表一个字符,如图给定一个字符串 char str[] = “hello”h的下标:‘h’ - ‘a’e的下标:‘e’ - ‘a’l的下标:‘l’ - ‘a’o的下标:‘o’ - ‘a’每个字符的下标相当于是该元素在该数组asscl码相对于起始值a的差值,a的值为97,h的值为104std::vecto原创 2021-06-27 16:23:16 · 1243 阅读 · 0 评论 -
数组类题目:leetcode 448 找到数组中所有消失的数字
题目描述:给定一个整数数组,其中所有值的范围在[1.n]之间,n是数组的长度数组中有些元素出现2次,有些元素只出现1次找到该范围内,没有出现在数组nums中的所有数组要求时间复杂度O(n),空间复杂度O(1)题目解析:关于“+n”的方法,与这篇文章一样:数组中重复的数据std::vector<int>* fun(int *arr,int len){ auto p = new std::vector<int>; for(int i = 0;i <原创 2021-06-27 15:09:34 · 114 阅读 · 0 评论 -
数组类题目:leetcode 442 数组中重复的数据
题目描述给定一个数组,其中数组中元素的范围是[1,n],n是数组的长度数组中有些元素出现2次,有些元素出现1次,找到所有出现2次的元素。要求:时间复杂度为0(n),空间复杂度为O(1)你可以假定返回的数组(存放元素的下标)不算在额外的空间内题目解析常规但不满足要求的解法:利用map表进行统计,边统计边查看当前元素的计数常规但不满足要求的解法:新开辟一个大小为n的数组,初始化都为0,该数组下标表示被统计数组中的元素,比数组元素值为8,对应该数组元素下标为7,遍历到就将下标7中的值进行+1.原创 2021-06-27 13:39:33 · 136 阅读 · 0 评论 -
数组类题目:统计数组元素出现的次数
假设不知道元素的数据范围:使用map遍历数组,将元素以及元素对应的计数存放在map中:void Count(int *arr,int len){ std::unordered_map<int,int> count_; for(int i = 0; i < len;++i) { auto it = count_.find(arr[i]); if(it != count_.end()) { i原创 2021-06-27 10:35:05 · 1193 阅读 · 0 评论 -
数组类题目:移动0,将数组中所有0移动到数组末尾
题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。必须在原数组上操作,不能拷贝额外的数组。尽量减少操作次数。题目解析:暴力法,遍历数组,遇到0就将后面往前移动,并从后往前给数组末尾赋值0void MoveZeroes(int *arr,int len){ int count = 0; for(int i = 0;i<len;++i) { if(arr[i] == 0) {原创 2021-06-26 16:27:24 · 7079 阅读 · 1 评论 -
数组类算法:移除元素
题目描述:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。题目解析:使用双指针法,从两头开始遍历,遇到目标数字,进行left++或者right++等操作。int RemoveElement(int *arr,int len,int elem){ int left = 0;原创 2021-06-26 14:57:56 · 165 阅读 · 0 评论 -
数组类题目:多数元素,找出数组中出现次数大于length/2的
题目描述给定一个数组,长度为n,找出数组中出现次数大于n/2的(该数组一定存在这个元素,个数超过n/2)。题目解析暴力求解:挨个进行次数统计,判断是否超过n/2int majorityElement(int *arr,int len){ int count = 0; for(int i = 0;i < len;++i) { for(int j = i+1;j<len;++j) { if(arr[j] =原创 2021-06-26 14:26:19 · 612 阅读 · 0 评论 -
数组类题目:找到数组三个数字和为target的数字,返回下标
题目描述:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0?找出所有满足条件且不重复的三元组。题目解析:暴力破解,三层循环扫数组双指针法void ThreeSum(int *arr,int length,int *result,int target){ //如果数组无序,先进行排序,sort,这里假设该数组已经有序 //假设arr[a] + arr[b] + arr[c] == target原创 2021-06-26 10:07:02 · 696 阅读 · 0 评论 -
数组类刷题:荷兰国旗问题
问题描述:给定一个数组,只能存放 0 1 2三个数字,给出一个算法,使得数组最终成00…11…22的形式,即0都集中在最前面,2集中在最后面。问题分析与code:排序,根据数据规模以及数据有序情况,选择一个排序算法;计数的方法,分别统计0 1 2个数,然后根据个数赋值数组:void Holland(int *arr,int len){ int count_0 = 0; int count_1 = 0; int count_2 = 0; for(int i原创 2021-06-24 16:10:44 · 160 阅读 · 0 评论 -
数组类题目:两数之和
题目描述给定一个数组arr,给定一个整数sum,寻找数组中是否存在两个数a1,a2,使得a1 + a2 == sum.题目解析以下是几种最容易想到的解决方式:暴力求解void TwoSum(int *arr,int *result,int len,int sum){ for(int i = 0;i<len;++i) { for(int j = i+1;j<len;++j) { if(arr[i]+arr[j原创 2021-06-24 14:55:13 · 220 阅读 · 0 评论 -
字符串类题目:将一个字符串循环左移k位
题目描述:将一个字符串循环左移k位,如字符串abcdef,循环左移2位为cdefab就像我们看到外面大街上的那个led展示屏幕上的内容滚动一样。题目解析:将整个字符串分为两个不同的串,s1 = ab + s2 = cdef将s1进行反转,得到ba,将s2也进行反转,得到fedc,最终得到了整个字符串s = bafedc然后将s进行反转,最终可以得到cdefab代码实现:#include <string.h>void ReverseString(char *s,int star原创 2021-06-24 13:48:20 · 579 阅读 · 0 评论 -
复习数据结构和算法基本概念
数据结构:相互之间存在一种或者多种特定关系的数据元素的集合,是组织数据的一种方式。在逻辑上可以分为线性结构、散列结构、树形结构、图形结构等。算法:算法是求解具体问题的步骤描述,代码上表现出来是解决特定问题的一组有限的指令序列。算法复杂度时间和空间复杂度,衡量算法效率,算法执行过程中,随着数据规模n的增长,算法执行所花费的时间和空间的增长速度。O(1):算法花费的时间与数据的量(规模)无关; 数组随机访问,哈希表O(logn):算法花费的时间与数据的量(规模)呈对数关系; 二分搜索、BST原创 2020-07-12 20:52:42 · 160 阅读 · 0 评论