- 博客(321)
- 收藏
- 关注

原创 数据结构绪论--数据结构相关知识点
数据结构是一门研究非数值计算的程序设计问题的操作对象以及它们之间的关系和操作的学科。程序设计=数据结构+算法什么是数据数据:描述客观事物的**符号**,是计算机可以操作的对象,是能被计算机识别,并输入给计算机处理的符号的集合。什么是数据元素数据元素:是数据的基本单位,在计算机程序通常作为一个整体考虑和处理一个数据元素可以又若干个数据项组成(注意:数据项是数据的不可分割的最小单位)什么是数据对象是性质相同的**数据元素**的集合,是数据的一个子集四类基本结构(1)集合 (2)线
2020-09-14 22:44:49
549
2

原创 前端基础知识--实现图片到网页的跳转
如何点击图片跳转到另外一个网页如何实现图片到网页跳转// An highlighted block<a href="选择跳转的页面的地址"><img src="图片的地址"></a>题目思考来源–菜鸟教程(“https://www.runoob.com/”)...
2020-06-14 22:07:29
941
原创 数组的最大美丽值
k,此时[left,right]的值都满足美丽值,更新最大长度,最后并进行返回。这题等价于,排序后的数组元素,通过右窗口-左窗口的值判断如果是否大于2。k,如果是收缩左窗口,直到小于等于2。
2025-08-14 17:23:02
135
原创 找到最长的半重复子字符串
使用滑动窗口法,left和right分别表示当前窗口的左右边界,初始化repeat为0,用于记录窗口内相邻字符相同的次数。遍历字符串,从right指针开始扫描,当发现相邻字符相同时,增加repeat。如果repeat超过1,则通过移动left指针来收缩窗口,直到窗口内只有一个相邻字符相同,减少repeat。每次移动right指针时,更新当前窗口的最大长度result。最后返回result即可。
2025-08-14 17:10:46
147
原创 最多K个重复元素的最长子数组
该算法结合了哈希表和滑动窗口的技术来求解问题。具体做法是,首先使用 right 指针遍历数组,并通过哈希表统计当前窗口内各个元素的出现次数。当窗口内某个元素的出现次数超过了给定的 k 时,表示当前窗口无效,需要通过移动左指针(即收缩窗口)来调整。每次移动左指针时,都更新哈希表中相应元素的出现次数,直到窗口内所有元素的出现次数都不超过 k。在此过程中,每次调整窗口后,更新当前窗口的最大长度。最终,返回窗口的最大长度作为结果。
2025-08-14 16:51:37
179
原创 乘积小于K的子数组
5.对于每个 right 指针的位置,所有从 left 到 right 的子数组都是合法的,加入到 count 中。该算法通过滑动窗口来解决问题,核心思想是维护一个窗口,窗口内的元素乘积始终小于给定的 k。1.初始化 left 指针和 cal(窗口内元素的乘积),count 用于记录符合条件的子数组个数。4.如果窗口内的乘积大于或等于 k,通过移动 left 指针(即缩小窗口)直到窗口内的乘积小于 k。3.每次扩展窗口时,将当前 right 指针所指的元素乘到 cal 中。
2025-08-14 16:45:13
198
原创 给植物浇水
此外,还需要考虑两人指针相遇时的情况:如果 Alice 的水量大于 Bob,但仍不足以浇灌当前植物,则重灌溉次数需加 1;同理,如果 Bob 的水量不足,也需加 1。
2025-08-14 16:15:17
184
原创 最接近的三数之和
这个题的思路与之前的“三数之和”题类似,都可以使用双指针来实现。具体做法是:遍历数组时,计算当前和,公式为“当前元素 + 左指针元素 + 右指针元素”。如果该和与目标值的差比当前最接近的和。根据当前和与目标值的大小关系,适当移动左右指针,直到遍历完成。最终返回最接近目标值的和。
2025-08-14 16:06:25
143
原创 有效三角形的个数
对数组排序,然后固定最右边nums[k],在最右边的前面使用双指针寻找两个数的和是否大于nums[k],如果满足nums[left]+nums[right]>nums[k]。那么从 left 到 right-1 的所有值与 nums[right] 也都满足条件,因此可以直接加上 right - left。
2025-07-30 16:22:59
132
原创 Leetcode 四数之和
为了避免重复的四元组,代码会跳过连续相同的数字,无论是对 i 还是对 j。在这些循环内部,它初始化两个指针 left 和 right,left 指向 j 之后的位置,right 指向数组末尾。这两个指针随后向内移动,寻找另外两个数字,使其与 nums[i] 和 nums[j] 相加后等于 target。如果和等于 target,则将该四元组添加到结果列表中,然后跳过 left 和 right 指针当前位置上所有紧邻的重复数字,以确保只记录唯一的四元组,之后再继续向内移动。
2025-07-30 16:06:25
265
原创 面试150 最大正方形
定义 dp[i][j] 表示以第 i 行第 j 列为右下角的最大正方形的边长。边界初始化时,若某一行或某一列中存在 ‘1’,则对应的 dp[i][0] 或 dp[0][j] 设为 1,并更新 max_side。对于内部的每个位置,如果当前位置是 ‘1’,则该位置能构成的最大正方形边长由其左、上和左上三个位置的最小值决定,即 dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1,同时更新当前最大边长 max_side。
2025-07-29 10:57:22
163
原创 面试150 编辑距离
定义动态规划数组dp[i][j]表示word1的前i个字符编辑成word2的前j个字符的最小操作数。初始化时,若一个字符串为空,则需要的操作数为另一个字符串的长度。状态转移时,如果当前字符相同,则不需要操作,继承 dp[i-1][j-1];否则取三种操作(插入、删除、替换)中的最小值加一,即 dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1。最终返回 dp[m][n],表示将整个 word1 转换成 word2 所需的最少操作数。
2025-07-29 10:42:33
177
原创 面试150 交错字符串
定义二维布尔数组 dp[i][j] 表示 s3 的前 i + j 个字符是否可以由 s1 的前 i 个字符和 s2 的前 j 个字符交错组成。初始化时,dp[0][0] 设为 True,表示空串可以交错组成空串;然后分别初始化第一列和第一行,表示只使用 s1 或 s2 的情况。状态转移时,若当前位置字符与 s3 匹配,且对应的前一个状态为 True,则当前位置也为 True。最后返回 dp[m][n],即判断是否能用整个 s1 和 s2 交错组成 s3。
2025-07-29 10:20:03
146
原创 面试150 最长回文子串
当 s[i] == s[j] 且 dp[i+1][j-1] = True 时,也有 dp[i][j] = True,即当前子串的两端字符相同,且中间部分也是回文,那么整个子串也是回文。当 s[i] == s[j] 且 j - i <= 1 时,dp[i][j] = True,即子串长度为1或2且两端字符相同时,该子串为回文(如 “a” 或 “aa”)。在动态规划过程中,每次当 dp[i][j] 为 True 时,更新当前记录的最长回文子串的长度及其起止位置。最终根据记录的左右边界返回最长回文子串即可。
2025-07-29 09:56:44
192
原创 面试150 不同路径Ⅱ
本题采用动态规划的方法来求解,其中 dp[i][j] 表示从起点到达位置 (i, j) 的路径总数。关键在于初始化:如果起点所在位置的元素不是障碍(即不为 1),则初始路径数设为 1。接着分别初始化第一行和第一列,如果当前位置不是障碍,且前一个位置可达,则路径数为 1,否则为 0。在填充整个 dp 数组的过程中,只要当前位置不是障碍,通过状态转移公式 dp[i][j] = dp[i-1][j] + dp[i][j-1] 更新路径总数。最终返回 dp[m-1][n-1],即到达终点的路径数。
2025-07-29 09:32:09
126
原创 面试150 三角形最大路径和
采用自底向上的动态规划思路。首先从倒数第二层开始向上遍历,每个位置的最小路径和由其下一层相邻的两个元素中的较小值加上当前位置值决定。通过不断更新 triangle 中的值,最终 triangle[0][0] 就保存了从顶到底的最小路径和。
2025-07-29 09:17:23
196
原创 面试150 最长递增子序列
定义 dp[i] 表示以第 i 个元素结尾的最长递增子序列的长度,初始时每个位置的最长子序列长度为 1。然后通过双重循环遍历每一对元素 j < i,如果 nums[i] > nums[j],说明 nums[i] 可以接在 nums[j] 的递增序列之后,更新 dp[i] = max(dp[i], dp[j] + 1)。最终返回 dp 中的最大值,即整个数组中最长递增子序列的长度。
2025-07-28 10:19:56
221
原创 面试150 零钱兑换
该题是典型的背包问题,采用动态规划解决零钱兑换问题。定义 dp[j] 表示凑成金额 j 所需的最少硬币数,初始化时将所有金额设置为无穷大(float(‘inf’)),表示不可达,只有 dp[0]=0,即凑成金额 0 不需要硬币。然后遍历每种硬币面额 coins[i],对于每个硬币,从 coins[i] 开始更新 dp[j],通过状态转移方程:dp[j] = min(dp[j], dp[j - coins[i]] + 1),表示当前金额 j 最少可以是原来值或使用当前硬币后更优的选择。否则返回最小硬币数。
2025-07-28 09:12:39
170
原创 面试150 单词拆分
考虑动态规划,首先需要构建初始化的dp数组,dp[i]为True表示以i长度的字串能由wordDict的单词组成。dp[0]要为True,否则后面递推下去都是False。
2025-07-28 09:03:04
336
原创 面试150 打家劫舍
该公式表示:对于第 i 间房子,要么选择不偷(即继承 dp[i - 1] 的最大收益),要么选择偷这间(那么就不能偷前一间,只能加上 dp[i - 2] 的最大收益),二者取较大值作为当前的最优解。我们采用动态规划来解决这个问题。定义 dp[i] 表示考虑偷取下标为 i 的房子时,所能获得的最大金额。
2025-07-28 08:52:33
439
原创 面试150 爬楼梯
我们可以从题目中发现一个规律:爬两级楼梯有 2 种方法,爬三级楼梯有 3 种方法,而爬一级楼梯显然只有 1 种方法(因为只能走一步)。进一步观察可以发现,爬三级楼梯的方法数等于爬一级楼梯和爬两级楼梯的方法数之和。也就是说,每一级台阶的走法都可以由前一级和前两级的走法推导出来,这正是斐波那契数列的规律。因此,我们可以得到递推公式:dp[i] = dp[i - 1] + dp[i - 2]。为了使递推公式在边界情况下也成立,我们将 dp[0] 初始化为 1,这样可以统一所有情况,保证逻辑的完整性。
2025-07-27 19:45:45
193
原创 面试150 数字范围按位与
只要 left < right,说明两者在某些低位上存在不同,为了找到它们的公共前缀(高位相同部分),不断将 left 和 right 同时右移(即除以2),直到它们相等,记录右移的次数 shift。最后,将相等的值左移 shift 位,补回原来去掉的低位0,即为最终结果。
2025-07-27 19:32:19
244
原创 面试150 阶乘后的零
尾随0是指阶乘结果末尾连续的零的数量。尾随0是因为乘法因子2*5导致的,阶乘计算中2的个数通常比5要多,所以决定尾0数量的是5的个数。因此,算法的目标是统计 n!中包含多少个因子 5。
2025-07-26 17:16:49
232
原创 面试150 查找和最小的K对数字
利用最小堆的方法,将 nums1 中前 k 个元素与 nums2[0] 组成的配对 (nums1[i] + nums2[0], i, 0) 压入堆中,表示从 nums2 的第一个元素开始匹配。然后每次从堆中取出当前和最小的数对 (i, j),加入结果中,并将对应 nums2[j+1] 的新配对 (nums1[i], nums2[j+1]) 加入堆中,逐步扩展。该方法充分利用了两个数组的有序性和堆结构,避免了暴力生成所有配对再排序,时间效率更高。
2025-07-26 16:33:54
148
原创 面试150 IPO
首先,将每个项目的启动资本需求和对应的利润配对,组成一个二元组列表,并根据所需资本从小到大进行排序。这样可以确保在遍历项目列表时,能按所需资本的升序处理。接着,使用一个最大堆(通过在堆中存入利润的负值来实现)来维护当前资本下所有可选项目的利润。在每一轮(最多进行 k 轮)中,程序会将当前可承受的所有项目(即资本需求不超过当前拥有资本的项目)加入最大堆,然后从中选择利润最高的项目(堆顶元素),执行该项目并将其利润加到当前资本上。最终,返回选择最多 k 个项目后所能获得的最大资本。
2025-07-26 16:00:42
157
原创 面试150 数组中的第K个最大元素
该算法通过最小堆(小顶堆)求解第 k 大元素。遍历数组 nums 时,将每个元素依次压入堆中,并保持堆的大小不超过 k。一旦堆中元素超过 k 个,就弹出堆顶最小值,从而始终保留当前最大的 k 个元素。最终堆顶元素即为第 k 大的数。直接对数组进行从小到大排序,根据要求进行相应的下标返回即可。
2025-07-25 09:34:27
210
原创 面试150 寻找旋转数组中的最小值
初始设定左右指针 left 和 right,循环条件为 left < right,每次取中点 middle。如果中点值大于右端值,说明最小值一定在右半部分,左指针移动到 middle + 1;否则说明最小值可能在左半部分甚至是 middle 本身,因此右指针移动到 middle。循环结束时,left == right,即为最小值所在的位置。直接return min(nums)即可。
2025-07-25 09:08:35
142
原创 面试150 在排序数组中查找元素的第一个和最后一个元素
通过两次二分查找定位目标值 target 的起始和结束位置。首先,如果 target 不在数组中,直接返回 [-1, -1]。第一次调用 binary(0, n-1, target) 找到 target 出现的最左位置 Left,第二次调用 binary(0, n-1, target+1) - 1 找到 target 出现的最右位置 Right。由于第二次查找的是 target+1,减一后刚好落在最后一个 target 上。直接搜寻法,通过记录target所对应的索引值,最后返回第一个和最后一个下标即可。
2025-07-25 08:56:17
107
原创 面试150 搜索旋转排序数组
使用伪二分法,每次循环中,先判断中间元素是否等于目标值;如果不等,就根据数组的旋转特性来判断哪一半是有序的。如果左半边有序(nums[left] <= nums[middle]),再判断目标值是否落在左半区间内;若是,则向左缩小搜索范围,否则向右。反之,如果右半边有序,则判断目标值是否落在右半区间内;若是,则向右缩小范围,否则向左。通过不断缩小搜索区间,最终找到目标值或返回 -1。暴力法直接判断元素是否在数组中,如果在返回其下标即可,如果不在返回-1。
2025-07-24 16:06:29
193
原创 面试150 寻找峰值
二分法:在每次查找中,通过比较中间位置 mid 的元素与其右侧元素 nums[mid + 1] 的大小关系,判断峰值所在的方向。如果 nums[mid] > nums[mid + 1],说明峰值可能就在 mid 或其左侧,因此将搜索区间缩小为左半部分;反之,则说明峰值必定在右侧,缩小搜索范围为右半部分。不断缩小区间,最终会收敛到某个峰值元素的索引。暴力法,直接返回最大元素所在下标,因为找到了最大元素,两边的元素肯定小于等于它。
2025-07-24 15:40:07
157
原创 面试150 搜索二维矩阵
Z字形搜索从矩阵的右上角(第一行最后一列)开始。若当前元素等于 target,则返回 True。如果当前元素小于 target,说明目标可能在更大的元素中,将行索引加一(向下移动);反之,若当前元素大于 target,则列索引减一(向左移动)。重复上述过程,直到找到目标或越界结束搜索。直接遍历搜寻,逐个判断即可。
2025-07-24 09:45:40
231
原创 面试150 搜索插入位置
使用二分法查找时,首先确定中间位置 middle。如果 nums[middle] == target,则直接返回 middle。若 nums[middle] < target,说明目标值在右半部分,将左指针更新为 middle + 1;反之,若 nums[middle] > target,则目标值在左半部分,更新右指针为 middle - 1。暴力法:首先判断target是否在nums中,如果在直接返回其下标即可,如果不在,将其插入到数组中,然后进行排序,返回其下标。
2025-07-24 09:39:00
162
原创 面试150 环形子数组的最大和
通过分情况处理,先求出非环形情况下的最大子数组和(max_sum),然后用类似方式求出最小子数组和(min_sum)。由于环形最大子数组可能由总数组和减去中间最小子数组得到,因此再计算总和 total - min_sum 与 max_sum 进行比较,取两者的较大值作为最终答案。注意到如果数组全为负数,此时 total - min_sum 等于 0,会误导结果,因此单独判断 max_num < 0 的情况,直接返回最大值,避免错误。该方法充分利用了Kadane算法的优雅特性,时间复杂度为 O(n)。
2025-07-23 19:04:21
210
原创 面试150 最大子数组和
动态规划法:首先定义动态规划数组dp=[float(‘-inf’)]*n,dp[i]表示以第i个元素结尾的最大连续子数组和,初始状态dp[0]为nums[0],递推的公式为当前最大的和要么是前一个元素+nums[i],要么是从当前元素nums[i]贪心法:设定最小标志result为float(‘-inf’),遍历一次数组元素进行求和,如果当前元素大于result,则更新result的值,如果sum小于0,则重新置0进行计算,最后返回result。重新开始,选择最大值进行更新,最后返回。
2025-07-23 15:12:42
211
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人