![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
weixin_46590256
这个作者很懒,什么都没留下…
展开
-
差分和前缀和专题
差分与前缀和是一对互逆的操作,常常用于处理区间问题,差分法是解决区间加减问题,前缀和是解决区间求和问题的常用办法。1.差分法差分法的特点:1.将对于区间的加减操作转化为对于端点的操作;2.时间复杂度为 O(n);3.用于维护区间的增减但不能维护乘除;4.差分后的序列比原来的数组序列多一个数。先差分,后加减,再还原,去掉最后一项。2.前缀法前缀和的特点:将对于区间的求和操作转化为对于端点值的减法的操作;区间求和操作的时间复杂度为 O(1);数组存放时要从 1 开始;前缀和数组比原来原创 2022-03-17 21:08:15 · 249 阅读 · 0 评论 -
递归专题(dfs,bfs)
递归DFS用递归的形式,用到了栈结构,先进后出。BFS选取状态用队列的形式,先进先出。1.路径之和给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22输出:true解题思路:递归(原创 2022-03-17 10:26:36 · 453 阅读 · 0 评论 -
动态规划专题
动态规划动态规划是自底向上,递归是自顶向下动态规划一般都脱离了递归,而是由循环迭代完成计算。关键是找到状态转移方程1.杨辉三角注意vector构建出来的二维数组两次初始化vector<vector<int> > dp(numRows);dp[i].resize(i+1);或者直接初始化 vector<vector<int> > newOne(r, vector<int>(c, 0));2.最长上升子序列输入:nums =原创 2022-03-17 09:07:48 · 139 阅读 · 0 评论 -
L61 旋转链表(链表)
描述1->2->3->4->5 ,k=2,输出4->5->1->2->3,将链表每个结点向右移动k个位置解题思路画图class Solution {public: ListNode* rotateRight(ListNode* head, int k) { if(!head) return nullptr; if(k==0) return head; ListNode* tmp=head;原创 2022-01-20 09:31:49 · 507 阅读 · 0 评论 -
L24两两交换链表中的结点(链表)
描述1->2->3->4 两两交换 2->1->4->3解题思路class Solution {public: ListNode* swapPairs(ListNode* head) { if(!head) return nullptr; ListNode* newhead=new ListNode(0); newhead->next=head; ListNode* pre=newhe原创 2022-01-20 08:58:46 · 54 阅读 · 0 评论 -
NC151 最大公约数(基础数学)
描述输入 a 和 b , 请返回 a 和 b 的最大公约数。输入:8,12返回值:4解题思路方法一:暴力class Solution {public: int gcd(int a, int b) { int c=min(a,b); for(int i=c;i>0;i--){ if(a%i==0 && b%i==0) return i; } re原创 2022-01-16 22:09:16 · 78 阅读 · 0 评论 -
NC142 最长重复子串(字符串)
描述定义重复字符串是由两个相同的字符串首尾拼接而成,例如 abcabcabcabc 便是长度为6的一个重复字符串,而 abcbaabcba 则不存在重复字符串。给定一个字符串,请返回其最长重复子串的长度。解题思路:枚举枚举的长度起始为n/2,因为长度大于字符串一半的子串必不会重复class Solution {public: bool judge(string& a,int start,int len){ for(int i=start;i<start+l原创 2022-01-13 10:23:18 · 317 阅读 · 0 评论 -
NC104 比较版本号(字符串)
描述现在给你2个版本号version1和version2,请你比较他们的大小版本号是由修订号组成,修订号与修订号之间由一个"."连接。1个修订号可能有多位数字组成,修订号可能包含前导0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本号每个版本号至少包含1个修订号。修订号从左到右编号,下标从0开始,最左边的修订号下标为0,下一个修订号下标为1,以此类推。比较规则:一. 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。比如"0.1原创 2022-01-13 09:46:31 · 267 阅读 · 0 评论 -
NC113 验证IP地址(字符串)
描述编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1;同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个原创 2022-01-12 11:13:49 · 126 阅读 · 0 评论 -
NC100 把字符串转换成整数(atoi)(字符串)
描述写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成:1.若干空格2.(可选)一个符号字符(’+’ 或 ‘-’)3. 数字,字母,符号,空格组成的字符串表达式转换算法如下:1.去掉无用的前导空格2.第一个非空字符为+或者-号时,作为该整数的正负号,如果没有符号,默认为正数3.判断整数的有效部分:3.1 确定符号位之后,与之后面尽可能多的连续数字组合起来成为有效整数数字,如果没有有效的整数部分,那么直接返回原创 2022-01-12 10:18:48 · 465 阅读 · 0 评论 -
NC31 第一个只出现一次的字符(字符串)
描述在一个长为 字符串中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数)要求:空间复杂度 O(n),时间复杂度 O(n)输入:“google”返回值:4解题思路:数组巧妙利用字母的ASCII码,使用ASCII码(对应数组的下标)表示字母,去统计字母出现的次数。最后我们只需要遍历一遍字符串,找到那个只出现一次的字符即可。class Solution {public: int FirstNotRepeatingChar(string原创 2022-01-11 11:03:04 · 107 阅读 · 0 评论 -
NC149 kmp算法(字符串)
描述给你一个文本串 T ,一个非空模板串 S ,问 S 在 T 中出现了多少次要求:空间复杂度 O(len(S)),时间复杂度 O(len(S)+len(T))输入:“ababab”,“abababab”返回值:2输入:“abab”,“abacabab”返回值:1解题思路kmp算法参考https://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html朴素方法慢是因为每次字原创 2022-01-11 10:53:24 · 302 阅读 · 0 评论 -
NC55 最长公共前缀(字符串)
描述给你一个大小为 n 的字符串数组 strs ,其中包含n个字符串 , 编写一个函数来查找字符串数组中的最长公共前缀,返回这个公共前缀。输入:[“abca”,“abc”,“abca”,“abc”,“abcc”]返回值:“abc”解题思路方法一:子串纵向查找纵向遍历非常的直观,将每个字符串分别依次遍历每一列的元素,比较相同列上字符是否相同,若相同则比较下一个子串,若不同则最长公共前缀为上个遍历过的公共前缀。复杂度分析:时间复杂度:O(mn),其中n 是字符串的数量,m 是字符串数组中的字符串原创 2022-01-10 16:21:08 · 378 阅读 · 0 评论 -
NC136 输出二叉树的右视图(树)
描述请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图如输入[1,2,4,5,3],[4,2,5,1,3]时,通过前序遍历的结果[1,2,4,5,3]和中序遍历的结果[4,2,5,1,3]可重建出以下二叉树:所以对应的输出为[1,3,5]。解题思路...原创 2022-01-10 09:55:46 · 171 阅读 · 0 评论 -
NC117 合并二叉树(树)
描述已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。输入:{1,3,2,5},{2,1,3,#,4,#,7}返回值:{3,4,5,5,4,#,7}解题思路class Solution {public: TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { if(t1==nullptr&&t2==nullptr) return null原创 2022-01-06 09:54:41 · 48 阅读 · 0 评论 -
NC161 二叉树的中序遍历(树)
中序遍历:左-中-右class Solution {public: void midorder(TreeNode* root,vector<int> &res){ if(root!=nullptr){ midorder(root->left, res); res.push_back(root->val); midorder(root->right,res);原创 2022-01-06 09:42:01 · 183 阅读 · 0 评论 -
NC157 单调栈(栈)
描述给定一个长度为 n 的可能含有重复值的数组 arr ,找到每一个 i 位置左边和右边离 i 位置最近且值比 arri 小的位置。请设计算法,返回一个二维数组,表示所有位置相应的信息。位置信息包括:两个数字 l 和 r,如果不存在,则值为 -1,下标从 0 开始。输入:[3,4,1,5,6,2,7]返回值:[[-1,2],[0,2],[-1,-1],[2,5],[3,5],[2,-1],[5,-1]]进阶:空间复杂度 O(n) ,时间复杂度 O(n)解题思路方法一:单调栈就是栈内元素有单调原创 2022-01-05 14:51:21 · 444 阅读 · 0 评论 -
NC90 包含min函数的栈(栈)
描述定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop、top 和 min 函数操作时,栈中一定有元素。此栈包含的方法有:push(value):将value压入栈中pop():弹出栈顶元素top():获取栈顶元素min():获取栈中最小元素进阶:栈的各个操作的时间复杂度是O(1) ,空间复杂度是 O(n)解题思路需要一个正常栈normal,用于栈的正常操作,然后需要一个辅助栈minval,专门用于获取最小值class Solutio原创 2022-01-05 13:31:56 · 131 阅读 · 0 评论 -
NC52 有效括号序列(栈)
描述给出一个仅包含字符’(’,’)’,’{’,’}’,’[‘和’]’,的字符串,判断给出的字符串是否是合法的括号序列括号必须以正确的顺序关闭,"()“和”()[]{}“都是合法的括号序列,但”(]“和”([)]"不合法。要求:空间复杂度 O(n),时间复杂度 O(n)解题思路:借助辅助栈左括号入栈,右括号和栈顶元素比较class Solution {public: bool isValid(string s) { stack<char> stk;原创 2022-01-05 13:11:41 · 300 阅读 · 0 评论 -
NC76 用两个栈实现队列(栈)
描述用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。要求:存储n个元素的空间复杂度为 O(n) ,插入与删除的时间复杂度都是 O(1)解题思路借助栈的先进后出规则模拟实现队列的先进先出1、当插入时,直接插入 stack12、当弹出时,当 stack2 不为空,弹出 stack2 栈顶元素,如果 stack2 为空,将 stack1 中的全部数逐个出原创 2022-01-04 09:47:49 · 66 阅读 · 0 评论 -
NC2 重排链表(链表)
描述将给定的单链表 L: L_0→L_1→…→L_{n-1}→L_ n重新排序为:L_0→L_n →L_1→L_{n-1}→L_2→L_{n-2}→…要求使用原地算法,不能只改变节点内部的值,需要对实际的节点进行交换。要求:空间复杂度 O(n) 并在链表上进行操作而不新建链表,时间复杂度 O(n)输入:{1,2,3,4}返回值:{1,4,2,3}解题思路开一个动态数组vector,然后,使用双指针的方法一个l,一个r,用来表示当前最前面可以选择的结点的位置和当前最后面可以选择的结点的位置。这原创 2022-01-04 09:28:39 · 493 阅读 · 0 评论 -
NC132 环形链表约瑟夫问题(链表)
描述编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。下一个人继续从 1 开始报数。n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?输入:5,2返回值:3说明:开始5个人 1,2,3,4,5 ,从1开始报数,1->1,2->2编号为2的人离开1,3,4,5,从3开始报数,3->1,4->2编号为4的人离开1,3,5,从5开始报数,5->1,1->2编号为1的人离开3,5,从3开始报数,3->原创 2022-01-03 22:01:23 · 74 阅读 · 0 评论 -
NC 链表中倒数最后k个结点(链表)
描述输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。如果该链表长度小于k,请返回一个长度为 0 的链表。解题思路:双指针可以设置两个指针,一个先走K步,剩下的到链表的末尾要走的步数就是倒数第k个节点,需要从头开始走的步数class Solution {public: ListNode* FindKthToTail(ListNode* pHead, int k) { ListNode* fast = pHead; Li原创 2022-01-03 20:41:28 · 162 阅读 · 0 评论 -
NC66 两个链表的第一个公共结点(链表)
描述输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。要求:空间复杂度 O(1),时间复杂度 O(n)可以看到它们的第一个公共结点的结点值为6,所以返回结点值为6的结点。解题思路:双指针关键在于如何让长度不同的链表变为相等。链表a长度为a,链表b长度为b,a!=b,但是a+b==b+aclass Solution {public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead原创 2021-12-30 10:31:54 · 261 阅读 · 0 评论 -
NC21 链表内指定区间反转(链表)
描述将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转要求时间复杂度 O(n),空间复杂度 O(1)例如:给出的链表为1→2→3→4→5→NULL, m=2,n=4,返回 1→4→3→2→5→NULL.解题思路反转局部链表,可以将该局部部分当作完整链表进行反转再将已经反转好的局部链表与其他节点建立连接,重构链表使用虚拟头节点的技巧,可以避免对头节点复杂的分类考虑,简化操作。class Solution {public: ListNode* reverseB原创 2021-12-29 11:53:17 · 607 阅读 · 0 评论 -
NC24 删除有序链表中重复的元素2(链表)
描述给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。例如:给出的链表为1→2→3→3→4→4→5, 返回1→2→5.给出的链表为1→1→1→2→3, 返回2→3.要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)解题思路:双指针class Solution {public: ListNode* deleteDuplicates(ListNode* head)原创 2021-12-29 09:44:17 · 40 阅读 · 0 评论 -
NC25 删除有序链表中重复的元素1(链表)
描述删除给出链表中的重复元素(链表中元素从小到大有序),使链表中的所有元素都只出现一次例如:给出的链表为1→1→2,返回1→2.解题思路class Solution {public: ListNode* deleteDuplicates(ListNode* head) { ListNode* p=head; if(head==nullptr) return head; while(p->next!=nullptr){原创 2021-12-28 11:06:31 · 231 阅读 · 0 评论 -
NC50 链表中的结点每k个一组翻转(链表)
描述将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样你不能更改节点中的值,只能更改节点本身。要求空间复杂度 O(1),时间复杂度 O(n)例如:给定的链表是 1→2→3→4→5对于 k = 2 , 应该返回 2→1→4→3→5对于 k = 3 , 应该返回 3→2→1→4→5解题思路class Solution {public: ListNode* reverseKGroup(ListNode* he原创 2021-12-28 10:59:12 · 553 阅读 · 0 评论 -
NC33 合并两个排序链表(链表)
描述输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。要求:空间复杂度 O(1),时间复杂度 O(n)解题思路初始化:定义cur指向新链表的头结点操作:如果l1指向的结点值小于等于l2指向的结点值,则将l1指向的结点值链接到cur的next指针,然后l1指向下一个结点值否则,让l2指向下一个结点值循环步骤1,2,直到l1或者l2为nullptr将l1或者l2剩下的部分链接到cur的后面class Solution {public: Lis原创 2021-12-26 11:02:44 · 79 阅读 · 0 评论 -
NC3 链表中环的入口节点(链表)
描述给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)解题思路方法一:哈希法1.遍历单链表的每个结点2.如果当前结点地址没有出现在set中,则存入set中3.否则,出现在set中,则当前结点就是环的入口结点4.整个单链表遍历完,若没出现在set中,则不存在环class Solution {public: ListNode* EntryNodeOfLoop(ListNode* phea原创 2021-12-25 11:41:01 · 719 阅读 · 0 评论 -
NC40 两个链表生成相加链表(链表)
描述假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。给定两个这种链表,请生成代表两个整数相加值的结果链表。要求:空间复杂度 O(n),时间复杂度 O(n)解题思路方法一:反转链表class Solution {public: ListNode* reverse(ListNode* head){ ListNode* pre = nullptr; ListNode* cur = head; ListNode原创 2021-12-25 10:58:08 · 511 阅读 · 0 评论 -
NC4判断链表中是否有环(链表)
描述判断给定的链表中是否有环。如果有环则返回true,否则返回false。要求:空间复杂度 O(1),时间复杂度 O(n)解题思路方法一:快慢指针class Solution {public: bool hasCycle(ListNode *head) { if(!head) return false; ListNode* slow = head; ListNode* fast = head; while(fast!=nul原创 2021-12-24 09:56:10 · 247 阅读 · 0 评论 -
NC78 反转链表(数组)
描述给定一个单链表的头结点pHead,长度为n,反转该链表后,返回新链表的表头。要求:空间复杂度 O(1),时间复杂度 O(n) 。解题思路方法一:可以先用一个vector将单链表的指针都存起来,然后再构造链表。class Solution {public: ListNode* ReverseList(ListNode* pHead) { if(!pHead) return nullptr; vector<ListNode* > v;原创 2021-12-24 09:39:54 · 822 阅读 · 0 评论 -
NC106 三个数的最大乘积(数组)
描述给定一个长度为 nn 的无序数组 AA ,包含正数、负数和 0 ,请从中找出 3 个数,使得乘积最大,返回这个乘积。输入:[3,4,1,2]返回值:24要求时间复杂度: O(n),空间复杂度: O(1)。解题思路遍历数组,找到最大的三个数和最小的两个数,三个数的最大乘积来源可能有两种,一种是三个最大的数相乘,另一种是两个最小的数和一个最大的数相乘class Solution {public: long long solve(int* A, int ALen) {原创 2021-12-23 10:04:54 · 354 阅读 · 0 评论 -
NC38 螺旋矩阵(数组)
描述描述给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。要求:空间复杂度 O(nm),时间复杂度 O(nm)输入:[[1,2,3],[4,5,6],[7,8,9]]返回值:[1,2,3,6,9,8,7,4,5]解题思路从最上面开始遍历,接着到边的时候就向下遍历,然后向左向上遍历,当一圈遍历结束的时候则进入里圈进行遍历。class Solution {public: vector<int> spiralOrder(vector<v原创 2021-12-23 09:51:00 · 516 阅读 · 0 评论 -
NC107 寻找峰值(数组)
描述给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于如输入[2,4,1,2,7,8,4]时,会形成两个山峰,一个是索引为1,峰值为4的山峰,另一个是索引为5,峰值为8的山峰。输入:[2,4,1,2,7,8,4]返回值:1说明:4和8都是峰值元素,返回4的索引1或者8的索引5都可以解题思路class Solution {public: int fi原创 2021-12-23 09:23:02 · 335 阅读 · 0 评论 -
NC27 集合的所有子集(一)(数组)
描述现在有一个没有重复元素的整数集合S,求S的所有子集注意:给出的子集中的元素必须按升序排列给出的解集中不能出现重复的元素输入:[1,2,3]返回值:[[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]要求:空间复杂度 O(n!)O(n!),时间复杂度 O(n!)O(n!)解题思路递归+回溯class Solution {public: vector<vector<int> > res; vector<vec原创 2021-12-22 09:58:51 · 67 阅读 · 0 评论 -
NC36 在两个长度相等的排序数组中找到上中位数(数组)
描述给定两个递增数组arr1和arr2,已知两个数组的长度都为N,求两个数组中所有数的上中位数。上中位数:假设递增序列长度为n,为第n/2个数输入:[1,2,3,4],[3,4,5,6]返回值:3说明:总共有8个数,上中位数是第4小的数,所以返回3。要求:时间复杂度 O(n),空间复杂度 O(1)解题思路双指针class Solution {public: int findMedianinTwoSortedAray(vector<int>& arr1, v原创 2021-12-22 09:41:54 · 198 阅读 · 0 评论 -
NC46 加起来和为目标值的组合(二)(数组)(回溯)
描述给出一组候选数 c 和一个目标数 t ,找出候选数中起来和等于 t 的所有组合。c 中的每个数字在一个组合中只能使用一次。注意:题目中所有的数字(包括目标数 t )都是正整数组合中的数字要按非递减排序结果中不能包含重复的组合组合之间的排序按照索引从小到大依次比较,小的排在前面,如果索引相同的情况下数值相同,则比较下一个索引。要求:空间复杂度 O(n!) , 时间复杂度 O(n!)输入:[100,10,20,70,60,10,50],80返回值:[[10,10,60],[10,20,原创 2021-12-19 10:19:57 · 232 阅读 · 0 评论 -
NC29 二维数组中的查找(数组)
描述在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]给定 target = 7,返回 true。给定 target = 3,返回 false。解题思路暴力搜索class Solution {public: bool Find(int t原创 2021-12-18 11:45:57 · 47 阅读 · 0 评论