
数据结构与算法
这里记录数据结构与算法的学习笔记
AAS48
一起学算法
展开
-
Leetcode 784. 字母大小写全排列(回溯)
给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。返回 所有可能得到的字符串集合。以 任意顺序 返回输出。数据量不大,可以直接暴力回溯。原创 2022-10-30 11:36:19 · 156 阅读 · 1 评论 -
892. 三维形体的表面积(技巧)
至于下边和右边的面积,由后面的柱体来减。首先,一个柱体一个柱体的看,每个柱体是由:2 个底面(上表面/下表面)+ 所有的正方体都贡献了 4 个侧表面积。输入:grid = [[1,1,1],[1,0,1],[1,1,1]]输入:grid = [[1,2],[3,4]]原创 2022-10-08 11:38:31 · 256 阅读 · 0 评论 -
Leetcode 最多删除一个字符得到回文(双指针,思路棒)
每次判断两个指针指向的字符是否相同,如果相同,则更新指针,将 low + 1,high - 1,然后判断更新后的指针范围内的子串是否是回文字符串。如果两个指针指向的字符不同,则两个字符中必须有一个被删除,此时我们就分成两种情况:即删除左指针对应的字符,留下子串 s[low+1:high],或者删除右指针对应的字符,留下子串 s[low:high−1]。定义左右指针,初始时分别指向字符串的第一个字符和最后一个字符,每次判断左右指针指向的字符是否相同,如果不相同,则不是回文串;) 的,会超出时间限制。原创 2022-10-04 20:01:03 · 318 阅读 · 0 评论 -
剑指 Offer II 024. 反转链表(原地修改)
在遍历链表时,将当前节点的指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。本题要设计一个时间复杂度O(n), 空间复杂度O(1)的算法来反转链表。输入:head = [1,2,3,4,5]输出:[5,4,3,2,1]原创 2022-10-03 14:46:07 · 261 阅读 · 0 评论 -
Leetcode 6189. 按位与最大的最长子数组(DP)
换句话说,令 k 是 nums 任意 子数组执行按位与运算所能得到的最大值。那么,只需要考虑那些执行一次按位与运算后等于 k 的子数组。考虑 nums 中进行 按位与(bitwise AND)运算得到的值 最大 的 非空 子数组。第i位的按位与最大值,要么是在前一位的基础上与运算,要么是自己本身。数组的按位与就是对数组中的所有数字进行按位与运算。给你一个长度为 n 的整数数组 nums。借助了动态规划:最长递增子数组的思想。返回满足要求的 最长 子数组的长度。子数组 是数组中的一个连续元素序列。原创 2022-09-25 12:32:20 · 261 阅读 · 0 评论 -
1740. 找到二叉树中的距离(DFS)
给定一棵二叉树的根节点 root 以及两个整数 p 和 q ,返回该二叉树中值为 p 的结点与值为 q 的结点间的 距离。也可以借助前面实现的求最近公共祖先的方法。如果能求出祖先,再直接去求两边的距离也可以。两个结点间的 距离 就是从一个结点到另一个结点的路径上边的数目。1、遍历每一个节点,看其能否到达p,q两个目标节点。如果都可以到达的情况下,保存一个距离的最小值。原创 2022-09-23 09:52:51 · 308 阅读 · 0 评论 -
Leetcode 340. 至多包含 K 个不同字符的最长子串(滑动窗口)
给你一个字符串 s 和一个整数 k ,请你找出 至多 包含 k 个 不同 字符的最长子串,并返回该子串的长度。注意时间复杂度的控制,如果无脑O(n^2)会超时。我这里用hash优化到了O(n)原创 2022-09-18 11:59:53 · 296 阅读 · 0 评论 -
Leetcode 删除有序数组中的重复项(I, II两题)
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。将最终结果插入 nums 的前 k 个位置后返回 k。原创 2022-09-17 16:22:54 · 164 阅读 · 0 评论 -
416. 分割等和子集(dp01背包,深刻理解动态规划)
给你一个 只包含正整数 的 非空 数组 nums。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。因此,我们定义dp[i][val] 表示前i个物品,能否凑出重量为val的这种方案。如果dp[i][val] = 1表示可以凑出,等于0表示不能凑出。因为要求是分成两个等和子集,所以其实我们可以理解为,本题思路非常巧妙,将其转成01背包的动态规划。经过本题之后,确实感觉对动态规划更有感觉了。状态转移:基本上和01背包一样的思想。原创 2022-09-17 15:32:03 · 191 阅读 · 0 评论 -
Leetcode 253. 会议室 II(上下车问题)
给你一个会议时间安排的数组 intervals ,每个会议时间都会包括开始和结束的时间 intervals[i] = [starti, endi] ,返回 所需会议室的最小数量。这样可以把上车和下车的时间分成两组,通过两个指针滑动的方式,判断同时在车上的最大数就可以了。不用在意是谁上车还是下车,只需要注意什么时候上下车就可以。【思路】:本题思路非常好,称为。原创 2022-09-17 14:29:16 · 675 阅读 · 0 评论 -
250. 统计同值子树(二叉树)
遍历每个节点,看每个节点形成的树是否都是同值的。如果是,就res++即可。给定一个二叉树,统计该二叉树数值相同的子树个数。同值子树是指该子树的所有节点都拥有相同的数值。原创 2022-09-17 13:06:33 · 658 阅读 · 0 评论 -
面试题 17.10. 主要元素(摩尔投票)
数组中占比超过一半的元素称之为主要元素。给你一个 整数 数组,找出其中的主要元素。若没有,返回 -1。请设计时间复杂度为 O(N) 、空间复杂度为 O(1) 的解决方案。大致思想是如果有不同的就相互抵消,最后剩下来的那个x是可能的值。这个算法在求主要元素,或占比比较大的元素时具有很好的效果。所以最后还得检验一遍。原创 2022-09-17 12:45:05 · 128 阅读 · 0 评论 -
面试题 17.09. 第 k 个数(技巧)
链接:https://leetcode.cn/problems/get-kth-magic-number-lcci/solution/di-k-ge-shu-jiu-shi-xiang-bu-tong-wei-he-san-zhi-z/例如,前几个数按顺序应该是 1,3,5,7,9,15,21。定义三个index 分别指向上面三个数列,下一个丑数一定是三个 index 代表的值中最小的那个。反过来说也是一样的,一个丑数 x3 / x5 / x7 就会得到某一个更大的丑数。来源:力扣(LeetCode)原创 2022-09-17 12:10:46 · 264 阅读 · 0 评论 -
1343. 大小为 K 且平均值大于等于阈值的子数组数目(滑动窗口模板题)
请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。给你一个整数数组 arr 和两个整数 k 和 threshold。原创 2022-09-16 12:10:02 · 129 阅读 · 0 评论 -
剑指 Offer II 085. 生成匹配的括号 (暴力回溯)
正整数 n 代表生成括号的对数,请设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。每个位置只有两种选择,放左括号或右括号。最后筛选掉不合格的括号组合。原创 2022-09-14 16:25:11 · 168 阅读 · 0 评论 -
Leetcode 231. 2 的幂(位运算)
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true;否则,返回 false。如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。2、如果一个数要想为2的幂,必然有 (n & n-1) == 0。这是因为2的幂的数,它减一之后必然所有位(除最高位外)都是1.【思路】:循环的方法就不说了,这里主要提一提位运算的思路。1、如果某个数为负数,那么肯定不是2的幂。代码可以一行搞定了。原创 2022-09-14 12:13:53 · 111 阅读 · 0 评论 -
Leetcode 2269. 找到一个数字的 K 美丽值(滑动窗口)
给你整数 num 和 k ,请你返回 num 的 k 美丽值。一道很明显的滑动窗口题。这个技巧学会之后解这类问题确实非常容易。一个 子字符串 是一个字符串里的连续一段字符序列。子字符串能整除 num。子字符串长度为 k。允许有 前缀 0。0 不能整除任何值。原创 2022-09-13 18:58:38 · 284 阅读 · 0 评论 -
剑指 Offer II 008. 和大于等于 target 的最短子数组(滑动窗口)
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0。给定一个含有 n 个正整数的数组和一个正整数 target。原创 2022-09-13 18:50:08 · 108 阅读 · 0 评论 -
239. 滑动窗口最大值(滑动窗口)
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。如果最大值还存在于窗口内部,其实就可以根据情况直接过。每次只需要比较新加入的nums[right]和max谁大即可。当left > maxindex时,即最大值已经离开滑动窗口了,那么就得从头更新一遍最大值了。我发现其实并不是每次都要从头搜整个窗口内的元素。返回 滑动窗口中的最大值。原创 2022-09-13 15:46:34 · 175 阅读 · 0 评论 -
Leetcode 1395. 统计作战单位数 (DP)
作战单位需满足: rating[i] < rating[j] < rating[k] 或者 rating[i] > rating[j] > rating[k] ,其中 0原创 2022-09-10 14:05:23 · 111 阅读 · 0 评论 -
Leetcode 946. 验证栈序列(经典题目)
给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false。这个问题是一个经典的数据结构题目。分多种情况进行模拟即可。原创 2022-09-09 16:16:23 · 119 阅读 · 0 评论 -
Leetcode 2327. 知道秘密的人数(思路很棒)
给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。第一天有一个人知道秘密,arr[1] = 1。因此,我们只需要一个空间在forget +2级别的数组。这是我自己想出来的一个办法:用一个数组解决。在第 1 天,有一个人发现了一个秘密。原创 2022-09-08 13:03:33 · 665 阅读 · 0 评论 -
Leetcode 1823. 找出游戏的获胜者(约瑟夫环,数组实现法)
确切地说,从第 i 名小伙伴顺时针移动一位会到达第 (i+1) 名小伙伴的位置,其中 1原创 2022-09-07 14:41:29 · 210 阅读 · 0 评论 -
Leetcode 802. 找到最终的安全状态(DFS + 记忆化搜索)
图由一个 索引从 0 开始 的 2D 整数数组 graph表示, graph[i]是与节点 i 相邻的节点的整数数组,这意味着从节点 i 到 graph[i]中的每个节点都有一条边。如果一个节点没有连出的有向边,则它是 终端节点。如果从该节点开始的所有可能路径都通向 终端节点 ,则该节点为 安全节点。判断一个节点是否是安全节点:1、如果其出度是终端节点,没问题。输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]节点 5 和节点 6 是终端节点,因为它们都没有出边。原创 2022-09-06 12:41:30 · 231 阅读 · 0 评论 -
leetcode 419. 甲板上的战舰(广搜)
换句话说,战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,其中 k 可以是任意大小。两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰)。给你一个大小为 m x n 的矩阵 board 表示甲板,其中,每个单元格可以是一艘战舰 ‘X’ 或者是一个空位 ‘.’ ,返回在甲板 board 上放置的 战舰 的数量。输入:board = [[“X”,“.”,“.”,“X”],[“.”,“.”,“.”,“X”],[“.”,“.”,“.”,“X”]]原创 2022-09-05 17:01:08 · 125 阅读 · 0 评论 -
Leetcode 1584. 连接所有点的最小费用(手撸普利姆算法)
连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi]。可以把set想象成一个大岛屿,每次都是找其他节点到这个大岛屿的最短距离,找到后把该节点并入这个大岛屿。请你返回将所有点连接的最小总费用。输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]原创 2022-09-05 12:13:01 · 336 阅读 · 0 评论 -
Leetcode 剑指 Offer II 063. 替换单词 (字典前缀树模板修改)
在英语中,有一个叫做 词根(root) 的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。注意:在建立词根的时候,要在单词末尾加一步,设置一个dicFin的布尔值,表示这里是词根的结束。现在,给定一个由许多词根组成的词典和一个句子,需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。搜索过程中,如果看到dicFin直接返回。原创 2022-09-04 14:00:34 · 236 阅读 · 0 评论 -
面试题 04.03. 特定深度节点链表(链表+层次遍历)
给定一棵二叉树,设计一个算法,创建含有某一深度上所有节点的链表(比如,若一棵树的深度为 D,则会创建出 D 个链表)。返回一个包含所有深度的链表的数组。先用层次遍历确定 哪些节点在哪些层次上。提示:单链表插入时可以用一个尾指针,比较方便。最后返回的结果是:若干条链表。所谓链表数组,意思就是,再构造每一层的链表。原创 2022-09-01 22:06:08 · 218 阅读 · 0 评论 -
Leetcode 684. 冗余连接(并查集模板)
给定往一棵 n 个节点 (节点值 1~n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n 的二维数组 edges ,edges[i] = [ai, bi] 表示图中在 ai 和 bi 之间存在一条边。请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n 个节点的树。如果有多个答案,则返回数组 edges 中最后出现的边。如果缺少某一条边的情况下,仍能让所有节点都处于一个集合内,那么就说明这条边是冗余的。...原创 2022-08-31 15:51:03 · 230 阅读 · 0 评论 -
Leetcode 208. 实现 Trie (字典前缀树)
boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true;Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);void insert(String word) 向前缀树中插入字符串 word。Trie() 初始化前缀树对象。原创 2022-08-25 13:10:31 · 93 阅读 · 0 评论 -
通过例子超级通俗学会最短路径:迪杰斯特拉、弗洛伊德算法
一、迪杰斯特拉算法二、弗洛伊德原创 2020-11-09 19:43:50 · 389 阅读 · 0 评论 -
数据结构:静态链表和动态链表的区别概述
一、静态链表连续的一片存储空间静态链表的数据结构:typedef struct{ int data; //静态链表节点中的数据 int cur; //静态链表节点中的游标}component;可以发现,静态链表中是没有指针的。一个节点去找它的后继是通过cur下标。二、动态链表传统的单链表不要求存储空间连续,靠指针找后继。判断题:静态链表与动态链表在元素的插入、删除方面类似,不需要做元素的移动。答:正确的。动态链表插入删除不用移动,这个不用多说。静态链表可以通过修原创 2020-11-09 17:54:19 · 5426 阅读 · 0 评论 -
数据结构之树、二叉树、森林关系
本文内容:树的存储结构、树与二叉树的相互转换、树与森林的遍历原创 2020-11-02 14:44:47 · 1335 阅读 · 0 评论 -
数据结构之矩阵的压缩存储、广义表
一、特殊矩阵的压缩存储主要是两个:对称矩阵和三对角矩阵。由于很多元素是相同或有规律的,那么我们可以节省空间,不存那些重复的元素或者为0的元素对称矩阵此时存储就只需要一个大小为n(n + 1)/2的一维数组就可以了,没必要再用二维。那么下面我们研究一下,二维数组中的元素aij,压缩存到一维数组中之后,它在什么位置呢?aij存到一维数组的:(i - 1)*i / 2 + j - 1(i - 1)*i / 2是aij前i - 1行的所有元素所占空间j - 1是行前面有多少元素。二、三角矩阵原创 2020-11-01 18:30:58 · 893 阅读 · 0 评论 -
数据结构之队列和栈的应用
本文介绍队列和栈的实际应用:括号匹配、表达式求值一、括号匹配问题【问题描述】:给定一个仅含有括号的字符串,如何去判断该括号序列是否合法呢?例如:()()合法,(())合法,【()】合法但((()不合法,【)【)不合法用栈来解决。下面开始模拟算法,走两遍比如第一种情况:【()】【】参考上面的算法思想,执行过程:1、先看第一个括号,因为是左括号,所以直接把第一个括号【,压入栈中。2、再看第二个,也是左括号(,所以直接扔进栈就行3、第三个括号是右括号),所以我们要弹出一个栈顶元素 (原创 2020-11-01 18:04:11 · 1490 阅读 · 0 评论 -
数据结构查找篇之散列查找
一、散列函数构造法二、直接定原创 2020-11-01 14:15:59 · 686 阅读 · 0 评论 -
数据结构之分块查找
字典就是一种分块查找,也可以叫索引试想:给你一本没有索引的字典,里面全部乱序,那么我们不得不用最低级的顺序查找法查找单词,即一页一页地翻,一个一个地对比,费时费力,给你一天时间可能都找不到某一个词…而有了分块这种操作,将首字母相同的单词放在一个集体里,查找起来可以帮助我们快速定位,效率大大提高,这就是分块查找。例子:如果我们按照这个样子建立起索引表,那么查找过程就非常轻松了。注意:索引查找要求块间有序,即第二块里面的所有元素都比第一块里面大,第三块里面的所有元素都比前两块大。比如上图查找4原创 2020-10-29 17:43:19 · 1840 阅读 · 0 评论 -
数据结构之拓扑排序、关键路径
本文内容包括:拓扑排序、关键路径一、拓扑排序在讲到拓扑排序之前,我们得先了解一下有向无环图、AOV网和AOE网这三个东西有向无环图(DAG):中间的就是有向无环图,自己对比一下AOV网和AOE网:AOV网用于拓扑排序,AOE网用于关键路径。引例1:排课表问题。我们需要确定哪一门课先修,哪一门课得在前一门课的基础上修引例2:如何判断一个有向图是否有环?拓扑排序出场对下面这个图进行拓扑排序,得到的序列用来设置课程表,就是合理的拓扑排序思想核心:每次找出入度为0的节点,将其加原创 2020-10-29 16:56:43 · 797 阅读 · 0 评论 -
数据结构中常用排序算法总结
常用排序算法总结本文包括:选择排序、简单插入排序、折半插入排序、希尔排序、冒泡排序、快速排序、归并排序、基数排序一、选择排序选择排序是最简单的一种排序算法,它的思想很简单,即:第一趟遍历整个无序的序列,然后将最小的放首位;第二趟继续遍历后面无序的序列,将第二小的放在第二位…故而时间复杂度是O(n^2)所以代码直接模拟即可//简单选择void select_sort(){ for(int i = 0;i < n;i++){ int min = arr[i], min_index =原创 2020-10-29 12:05:38 · 385 阅读 · 0 评论 -
C语言:求单链表结点的阶乘和
本题要求实现一个函数,求单链表L结点的阶乘和。这里默认所有结点的值非负,且题目保证结果在int范围内。函数接口定义:int FactorialSum( List L );其中单链表List的定义如下:typedef struct Node *PtrToNode;struct Node { int Data; /* 存储结点数据 */ PtrToNode Next; /*...原创 2019-10-24 14:57:07 · 4656 阅读 · 1 评论