优选算法
文章平均质量分 67
c无序
这个作者很懒,什么都没留下…
展开
-
前缀和4️⃣-除自身以外数组的乘积
类似,就不多介绍啦,也是建立函数关系第i个位置前面的积 = 第i-1个位置前面的积 * 第i-1个位置的数据。注意题目的要求,不能使用除法,并且要在 0(N) 的时间复杂度内完成该题。那么我们就不能使 用暴力的解法,以及求出整个数组的乘积,然后除以单个元素的方法。before 存[0,i-1] 的积 , after存[i+1,n-1]的积。输入: nums = [-1,1,0,-3,3]输入: nums = [1,2,3,4]输出: [24,12,8,6]输出: [0,0,9,0,0]原创 2024-09-10 21:27:41 · 254 阅读 · 0 评论 -
前缀和3️⃣-寻找数组的中心下标(两种解法)
▪ 然后,我们可以用一个 for循环枚举可能的中心下标,判断每一个位置的「前缀和」以及「后缀和」,如果二者相等,就返回当前下标。左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0。是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。原创 2024-09-03 13:10:28 · 232 阅读 · 0 评论 -
前缀和2️⃣-二维前缀和
类比于一维数组的形式,如果我们能处理出来从[0, 0] 位置到 [i, j] 位置这片区域内所有元素的累加和,就可以在O(1) 的时间内,搞定矩阵内任意区域内所有元素的累加和。sum[i] [j] 表示,从下图的红色区域:[0, 0] 位置到 [i, j] 位置这段区域内,所有元素的累加和。✸ 如果把上面求的三个值加起来,那就是黄 + 红 + 蓝 + 红 + 绿,发现多算了一部分红的面积,因此再单独减去红的面积即可;✸ 红的面积正好也是符合 dp 数组的定义的,即 sum[i - 1] [j - 1]原创 2024-08-30 10:01:49 · 325 阅读 · 0 评论 -
前缀和1️⃣-一维前缀和
【代码】前缀和1️⃣-一维前缀和。原创 2024-08-27 09:56:32 · 170 阅读 · 0 评论 -
二分算法8️⃣-0~n-1 中缺失的数字(easy)
关于这道题中,时间复杂度O(N) 的解法有很多种,而且也是比较好想的,这里就不再赘述。本题只讲解一个最优的二分法,来解决这个问题。输入: records = [0, 1, 2, 3, 4, 5, 6, 8]点名结果记录于升序数组。▪ 在第一个缺失位置的左边,数组内的元素都是与数组的下标相等的;▪ 在第一个缺失位置的右边,数组内的元素与数组下标是不相等的。因此,我们可以利用这个「二段性」,来使用「二分查找」算法。输入: records = [0,1,2,3,5]假定仅有一位同学缺席,请返回他的学号。原创 2024-08-24 10:52:56 · 325 阅读 · 0 评论 -
二分算法7️⃣-搜索旋转排序数组中的最小值
通过图像我们可以发现, [A,B] 区间内的点都是严格大于 D 点的值的, C 点的值是严格小于 D 点的值的。▪ 当 mid 在 [A,B] 区间的时候,也就是 mid 位置的值严格大于 D 点的值,下一次查询区间在 [mid + 1,right] 上;▪ 当 mid 在 [C,D] 区间的时候,也就是 mid 位置的值严格小于等于 D 点的值,下次查询区间在 [left,mid] 上。解释:原数组为 [0,1,2,4,5,6,7] ,旋转 3 次得到输入数组。输入:nums = [3,4,5,1,2]原创 2024-08-21 15:17:36 · 379 阅读 · 0 评论 -
二分查找6️⃣-寻找峰值
此时「左侧区域」一定会存在山峰(因为最左侧是负无穷,那么我们可以去左侧去寻找结果):此时「右侧区域」一定会存在山峰(因为最右侧是负无穷,那么我们可以去右侧去寻找结果),找到峰值元素并返回其索引。当我们找到「二段性」的时候,就可以尝试用「二分查找」算法来解决问题。解释:3 是峰值元素,你的函数应该返回其索引 2。输入:nums = [1,2,1,3,5,6,4]解释:你的函数可以返回索引 1,其峰值元素为 2;或者返回索引 5, 其峰值元素为 6。输入:nums = [1,2,3,1]的算法来解决此问题。原创 2024-08-16 13:27:00 · 349 阅读 · 0 评论 -
二分查找5️⃣-山脉数组的封顶索引
对于山峰来说,我们会发现封顶的值是最大,对于封顶左边来说,后一个数比前一个数大;◦ 如果 mid 位置呈现上升趋势,说明我们接下来要在 [mid + 1, right] 区间继续搜索;◦ 如果 mid 位置呈现下降趋势,说明我们接下来要在 [left, mid - 1] 区间搜索;◦ 因此,我们可以遍历数组内的每一个元素,找到某一个元素比两边的元素大即可。本题的数组不是有序数组,但我们依然可以使用二分查找,原因是因为我们发现了。输入:arr = [0,2,1,0]◦ 峰顶的特点:比两侧的元素都要大。原创 2024-08-15 20:44:43 · 372 阅读 · 0 评论 -
二分查找4️⃣-x的平方根
因为我们找到结果之后直接就返回了,往后的情况就不会再判断。反而研究枚举区间,既耽误时间,又可能出错)解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。 ▪ [index + 1, x] 之间的元素,平方之后都是大于 x 的。 ▪ [0, index] 之间的元素,平方之后都是小于等于 x 的;不允许使用任何内置指数函数和算符,例如。,说明之前的一个数是结果,返回。由于返回类型是整数,结果只保留。这里没有必要研究是否枚举到。因此可以使用二分查找算法。原创 2024-08-15 20:43:42 · 255 阅读 · 0 评论 -
二分查找3️⃣-搜索插入位置
▪ 当 nums[mid] < target 时,说明 mid 落在了[left, index - 1]区间上,mid 右边但不包括 mid 本身,可能是最终结果,所以我们接下来查找的区间在[mid + 1, right]上。▪ 当 nums[mid] >= target 时,说明 mid 落在了[index, right] 区间上,mid 左边包括 mid 本身,可能是最终结果,所以我们接下来查找的区间在 [left,mid] 上。输入: nums = [1,3,5,6], target = 2。原创 2024-08-09 13:42:24 · 311 阅读 · 0 评论 -
二分查找2️⃣-在排序数组中查找元素的第一个和最后一个位置
◦ 当 mid 落在 [resRight+ 1, right] 的区间的时候,说明 [mid, right] 内的元素是可以舍去的,此时更新 right 到 mid - 1 的位置;❍ 关于什么时候用三段式,还是二段式中的某一个,一定不要强行去用,而是通过具体的问题分析情况,根据查找区间的变化确定指针的转移过程,从而选择一个模版。❍ 用的还是二分思想,就是根据数据的性质,在某种判断条件下将区间一分为二,然后舍去其中一个区间,然后在另一个区间内查找;要搜索的区间,根据分析问题来写出二分查找算法的代码。原创 2024-08-08 09:38:58 · 545 阅读 · 0 评论 -
二分查找简介+二分查找1️⃣
1️⃣ 特点:最恶心,细节最多,最容易写出死循环的算法。当然如果会应用的话,也会变成最简单的。2️⃣ 学习中的侧重点❍ 算法原理:不一定是数组有序的情况才能使用二分算法❍ 模版(不要死记硬背-> 理解之后再记忆)1.朴素的二分模版(easy but 局限)2.查找左边界的二分模版3.查找右边界的二分模版。(2,3 万能 但是细节多)原创 2024-08-07 18:44:02 · 453 阅读 · 0 评论 -
滑动窗口8-最小覆盖子串(hard)
当动态哈希表中包含目标串中所有的字符,并且对应的个数都不小于目标串的哈希表中各个字符的个数,那么当前的窗口就是一种可行的方案。·我们可以使用两个哈希表,其中一个将目标串的信息统计起来,另一个哈希表动态的维护窗口内字符串的信息。解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。解释: t 中两个字符 'a' 均应包含在 s 的子串中,中某个字符的数量大于窗口中字符的数量,也就是。中存在这样的子串,我们保证它是唯一的答案。输入:s = "a", t = "a"原创 2024-08-05 18:46:13 · 410 阅读 · 0 评论 -
滑动窗口7-串联所有单词的子串(困难
输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]它是 words 中以 ["the","foo","bar"] 顺序排列的连接。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]原创 2024-08-04 15:34:55 · 816 阅读 · 0 评论 -
滑动窗口练习6-找到字符串中所有字母异位词
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。输入: s = "cbaebabacd", p = "abc"的长度相同的滑动窗口,并在滑动中维护窗口中每种字母的数量;输入: s = "abab", p = "ab"原创 2024-07-27 16:08:44 · 304 阅读 · 0 评论 -
滑动窗口练习5-水果成篮(字节跳动)
一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。解释:可以采摘 [1,2,1,1,2] 这五棵树。输入:fruits = [1,2,3,2,2]解释:可以采摘 [2,3,2,2] 这四棵树。输入:fruits = [0,1,2,2]解释:可以采摘 [1,2,2] 这三棵树。,返回你可以收集的水果的。原创 2024-07-08 10:40:38 · 405 阅读 · 0 评论 -
滑动窗口练习4-将x减到0的最小操作数
题目要求的是数组「左端 + 右端」两段连续的,和为 x 的最短数组,信息量稍微多一些,不易理清思路;解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0。输入:nums = [3,2,20,1,1,3], x = 10。输入:nums = [1,1,4,2,3], x = 5。解释:最佳解决方案是移除后两个元素,将 x 减到 0。输入:nums = [5,6,7,8,9], x = 4。此时,就是熟悉的「滑动窗口」问题了。数组以供接下来的操作使用。原创 2024-07-06 11:35:25 · 316 阅读 · 0 评论 -
滑动窗口练习3-最大连续1的个数(三)
初始化一些变量 left = 0,right = 0,ret = 0;输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3。不要去想怎么翻转,不要把问题想的很复杂,这道题的结果无非就是一段连续的 1 中间塞了 k 个 0 嘛。解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2。解释:[1,1,1,0,0,1,1,1,1,1,1]原创 2024-07-05 14:34:03 · 353 阅读 · 0 评论 -
滑动窗口练习2-无重复字符的最长字串
再往后寻找无重复字串能到达的位置时,可以利用「哈希表」统计出字符出现的频次,并判断什么时候字串出现了重复元素。如果这个字符出现的频次超过 1 ,说明窗口内有重复元素,那么就从左侧开始划出窗口,请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。由英文字母、数字、符号和空格组成。原创 2024-06-21 09:52:06 · 282 阅读 · 0 评论 -
滑动窗口练习1-长度最小的子数组
但是如果继续像方法一一样,重新开始统计第二个元素( left2 )往后的和,势必会有大量重复的计算(因为我们在求第一段区间的时候,已经算出很多元素的和了,这些和是可以在计算下次区间和的时候用上的)。这个窗口寻找的是:以当前窗口最左侧元素(记为 left1 )为基准,符合条件的状况,也就是在这道题中,从 left1 开始,满足区间和 sum >=target 时的最右侧(记为 right1 )能到哪里。输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0。原创 2024-06-19 10:05:43 · 889 阅读 · 0 评论 -
双指针练习:四数之和
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target。请你找出并返回满足下述全部条件且。2.在这个数 a 的后面区间上,利用「三数之和」找到三个数,使这三个数的和等于 target - a 即可。输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]输入:nums = [1,0,-1,0,-2,2], target = 0。输入:nums = [2,2,2,2,2], target = 8。输出:[[2,2,2,2]]1.一次固定一个数a;原创 2024-06-17 16:02:27 · 260 阅读 · 0 评论 -
双指针练习:三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i!= k ,同时还满足 nums[i] + nums[j] + nums[k] == 0。那么三数之和就是固定一个数,找到两个数相加等于固定这个数的相反数,于是三数之和🟰0;不同的三元组是 [-1,0,1] 和 [-1,-1,2]。输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]输入:nums = [0,0,0]输出:[[0,0,0]]原创 2024-06-14 07:59:40 · 570 阅读 · 0 评论 -
双指针练习:和为s的两个数字
购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。输入:price = [3, 9, 12, 15], target = 18输出:[3,15] 或者 [15,3]输入:price = [8, 21, 27, 34, 52, 66], target = 61输出:[27,34] 或者 [34,27]两层for循环:·外层 for 循环依次枚举第一个数a;·内层 for 循环依次枚举第二个数b,让它与a匹配。原创 2024-06-13 10:43:57 · 424 阅读 · 0 评论 -
双指针练习:有效三角形的个数
根据「解法一」中的优化思想,我们可以固定一个「最长边」,然后在比这条边小的有序数组中找出一个二元组,使这个二元组之和大于这个最长边。2 + 9 > 10(最小的➕次大的数大于最大的数,那么left 与 right之间所有的数与9相加都大于10,也就是有right - left边都满足,此时可以right--)此时,边长为10最大的边情况已经遍历完毕,接下来max--,继续以同样的方式,遍历出每个符合构成三角形的边,累加即可解出此题。三层 for 循环枚举出所有的三元组,并且判断是否能构成三角形。原创 2024-06-13 10:42:37 · 561 阅读 · 0 评论 -
双指针练习:盛水最多的容器
由此可看无论怎么移动 v 都会变小,这里可以总结一个规律:如果移动之后的数,小于left与right原先所对应的值,那么这个新的v,一定比原来小。当我们不断重复上述过程,每次都可以舍去大量不必要的枚举过程,直到left 与 right相遇,期间产生的所有容积里面的最大值,就是最终答案。我们假设左边界最小,那么此时移动left,遇到的数比left大,就会改变高度最小值(2->5),这样v就有可能增大。如果移动之后的数比原来的大,那么高度是不变的,width是变小的,因此v变小。返回容器可以储存的最大水量。原创 2024-06-02 10:01:19 · 1034 阅读 · 0 评论 -
双指针练习:快乐数
由此可以推出:一个数经过不停的分割成下一个数,经过811次 这个分割后的数一定会出现重复的情况,也就是会进环,因此我们使快慢指针追击即可。我们来计算这个数每个位置上的数字的平方和,9^2 * 10 = 810,也就是最大的数是810。题目n最小为1,所以每个位置上的数字平方和的范围在 [1,810] 之间,有810个数。n个巢,有n+1个鸽子,可以推出至少有一个巢,里面的鸽子数大于1;由此我们可以发现:如果数n 是一个快乐数,它的最后一个数是1。如果数n 不是快乐数,它最终会形成一个环,不停的循环下去。原创 2024-06-01 10:00:45 · 607 阅读 · 0 评论 -
双指针练习:复写0
(越界的原因是因为cur 位置为0,des+=2 ,越界了一位,修改了一位数组以外的数据为0,即非法访问,因此,此时我们只需要修改一个dest为0就可以了,因此先手动修改arr[n-1] = 0 ,此时cur当前指的0也就我们手动修改过了,因此cur--,dest-=2)给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。·如果是0,dest以及dest -1位置修改成0,dest-=2;·如果非0,dest位置的数据 = cur位置的数据,dest--;原创 2024-05-31 13:06:46 · 583 阅读 · 0 评论 -
优选算法一:双指针算法与练习(移动0)
3.cur指针开始向后移动,为了实现【des+1 ,cur-1】中间是0,那么控制cur的条件就是,cur遇到0就跳过,也就是继续往前走。如果遇到了不是0,那么就将des+1,进行交换,交换后cur当前位置就变成了0,继续加加,直到遍历完数组。根据cur在扫描的过程中,遇到不同的情况,分类处理,实现数组的划分。2.既然cur指针在首元素,为了实现数组被划分三个阶段,那么des只能在cur之前的位置也就是 -1 处。·在一次循环中,每次让慢的指针向移动一位,而快的指针往后移动两位,实现一快一慢。原创 2024-05-30 20:08:49 · 762 阅读 · 0 评论