算法
丶孤独的牧羊人
网络安全研究生一枚
展开
-
LeetCode刷题日志-153.寻找旋转排序数组中的最小值
这道题我说说自己的理解, 首先二分的根本是有序,只要有序就能二分,哪怕是部分有序(这个是重点!) 我们先搞清楚题目中的数组是通过怎样的变化得来的,基本上就是等于将整个数组向右平移(想象一个圆形的环)。重点来了,不管怎么移,数组总有一半是有序的!要么左半边完全有序,要么右半边完全有序。那么大家可以想想,最小值在有序的那半边还是无序的那半边。答案很显然是在无序的那半边(想想数组是如何变化得来的)。那就很简单了,每一次二分都找无序的那一半,到最后剩下的就是最小值。原创 2024-03-25 10:26:33 · 338 阅读 · 0 评论 -
LeetCode刷题日志-34在排序数组中查找元素的第一个和最后一个位置
写二分查找对于边界的处理要细心,建议直接记:循环条件为 <=,left=0 right = nums.length - 1;思路:用两次二分查找,分别查找指定元素的第一个和最后一个位置。原创 2024-03-24 18:09:07 · 230 阅读 · 0 评论 -
leetcode刷题日志-108/1382将有序数组转换为二叉搜索树/将二叉搜索树变平衡
思路:这里我们是有了一颗二叉搜索树,将树变平衡,我们有了二叉搜索树,那么就有了升序序列,有了升序序列,不就跟108题一样了吗?将有序数组转换为平衡二叉搜索树。获取升序序列就使用中序遍历记录即可,后面的操作就是使用升序序列构建二叉平衡树了。思路:给定的数组已经升序排列,而二叉搜索树中序遍历的结果就是升序,但是仅凭中序遍历不能确定一颗二叉树,但是题目只是说将升序序列转换为平衡二叉搜索树,且答案不唯一,所以不要求。那么我们就能通过每次取数组最中间的元素作为二叉树节点最终就能构建整个平衡二叉搜索树。原创 2024-03-14 22:57:59 · 380 阅读 · 0 评论 -
LeetCode刷题日志-46.全排列
我们可以设置一个boolean数组,数组大小等于nums1的大小,用于记录nums中的元素有没有被使用,如果被使用,我们在选择添加元素时可以不添加,那么就不会有重复元素出现,得到的最终结果也就是全排列。跟77题组合一样,在这里又遇到同样的问题,如果使用暴力解法,nums大小不同,使用的循环嵌套的层数也不同。因为上面这段代码在每次递归都会从nums[0]开始,所以会出现重复。我们看以下代码,如果nums = [1,2,3]会输出什么?发现他每个元素都会重复出现,为什么会这样?这里就是从最内层开始遍历。原创 2024-03-11 11:33:55 · 256 阅读 · 0 评论 -
leetcode刷题日志-77.组合
但是这里存在一个问题就是,k不同我们循环嵌套的层数也不同,如果k=50,我们不可能写50个循环。所以这个方法pass掉。注意:这里不能再考虑 1,因为包含 1 的组合,在第 1 种情况中已经包含。如果组合里有 1 ,那么需要在 [2, 3, 4] 里再找 1个数;如图我们只要能得到这颗树上所以叶子节点的值,就能得到最终结果。如果组合里有 2 ,那么需要在 [3, 4] 里再找 1数。对于树形结构,我们就可以利用递归的思想去解决。依题,我们首先想到的是。原创 2024-03-09 23:19:43 · 257 阅读 · 0 评论 -
LeetCode刷题日志-17.电话号码的字母组合
纯暴力解法,digits有多长,就循环多少次进行字母组合。原创 2024-03-05 20:57:56 · 406 阅读 · 0 评论 -
LeetCode刷题日志-130.被包围的区域
根据这一发现,我们只要搜索每一个区域,判断它是否包含边界的。完当前的位置后,我们可以知道当前位置区域是否包含边界的。根据以上分析,我们可以遍历整个二维数组,每当遇到一个。,如果包含我们不对该区域进行填充,如果不包含,再调用。依题意,只要某个区域包含边界的。,同时判断是否包含边界的。那么这个区域就不能被。原创 2024-02-26 23:31:09 · 225 阅读 · 0 评论 -
LeetCode刷题日志-200.岛屿数量
思路: 遍历二维数组,每当遇到一个‘1’进行一次dfs,根据规则,将本次dfs到的所有元素标记为‘0’(放置重复dfs,并且能dfs到的元素一定是与当前遍历到的元素属于统一岛屿。)最后,dfs的次数就是岛屿的数量。原创 2024-02-23 23:50:26 · 358 阅读 · 0 评论 -
leetcode刷题日志-98.验证二叉搜索树
思路:根据二叉搜索树的性质,中序遍历满足升序。那么我们就可以使用中序dfs,并且记录每个节点的前一个节点的值,如果前一个节点值比后一个大,返回false。递归一看就会一写就废,同学们多练习,多思考,多理解即可。原创 2024-02-23 23:44:48 · 318 阅读 · 0 评论 -
LeetCode刷题日志-117填充每个节点的下一个右侧指针II
因为在二叉树每一层中,next指针指向的是的当前节点的右边的节点,所以,使用层序遍历,在每个节点出队后,指向当前层的下一节点,这样,遍历完整个树,next指针也就设置好了。二叉树的题目,我认为二叉树必须要掌握递归的三种遍历算法,以及层序遍历算法才能做二叉树题目。原创 2024-01-31 22:54:40 · 302 阅读 · 0 评论 -
leetcode刷题日志-146LRU缓存
思路:使用hashmap储存key,vaule,使用双向链表以快速查到尾结点(待逐出的节点),链表的题一定要在纸上画一下,不然连着连着就不知道连在哪里去了。原创 2024-01-28 16:30:00 · 928 阅读 · 0 评论 -
leetcode刷题日志-25k个一组翻转链表
思路,使用map存每组翻转后的链表,链表翻转使用头插法,最后再连接整个map的链表以及剩余的小于k个的节点。其余就是注意边界等细节问题。纪念一下:第首次一次提交通过的困难题。原创 2024-01-23 17:34:29 · 491 阅读 · 0 评论 -
leetcode刷题日志-383赎金信
思路:分别用两个map记录ransomNote和magazine中的字符以及出现的次数。最后遍历记录ransomNote的map,如果ransomNote的map中出现的magazine的map中没有出现或者出现的次数小于ransomNote的map则返回false,否则返回true;原创 2023-12-17 23:02:26 · 161 阅读 · 0 评论 -
leetcode刷题日志-289生命游戏
思路:用一个m*n的矩阵储存当前元素周围为1的元素数量。原创 2023-12-15 15:45:21 · 116 阅读 · 0 评论 -
LeetCode刷题日志-73矩阵置零
思路三:再思考观察,我们发现,除去第一行和第一列,若元素matrix[i][j]为0,那么matrix[i][0]与matrix[0][j]也必0。我们就可以利用第一行第一列记录需要置0的行和列。原地置零,空间复杂度O(1)。通过观察我们发现,只要一个元素为0,那么它所在的行和列都为0。我们只需记录下来所有0元素的行和列,就能将矩阵置0。用一个同样大小的矩阵记录0的位置,然后遍历矩阵置0,不知道为什么表现没有思路2的好。那么空间复杂度为O(m+n)相对比与思路一,有所进步。空间复杂度为O(mn)原创 2023-12-12 22:00:44 · 179 阅读 · 0 评论 -
leetcode刷题日志-54螺旋矩阵
每走完一行或者一列,移动相应边界,当左边界大于右边界,或者上边界大于下边界时,结束。上下左右设置四个边界。原创 2023-12-09 21:00:14 · 115 阅读 · 0 评论 -
LeetCode刷题日志-30串联所有单词子串
题目说明子串是包含words中所有单词,且任意顺序,我们可以使用一个map来存储words中每个单词以及对应数量,当我们在扫描s的时候,再使用一个map存储当前扫描的子串单词,扫描完当前子串后,我们可以对比两个map,如果相等,说明符合题目要求,不相等则不符合。最简单的思路就是,将words里的单词全排列,然后在s中比对,但是复杂度太高阶乘级别。原创 2023-11-30 16:07:45 · 92 阅读 · 0 评论 -
leetcode刷题日志-15.三数之和
这道题还是有点难度,我能想到的就是三重循环,但是题目限制不能重复,所以这道题三重循环完还要去重,太过于麻烦。看了题解以后,大佬们还是厉害,大概思路是这样子的:先对数组进行排序,然后在循环内固定一个数nums[i],在这个数后面的两端设置两个指针,移动两个指针判断是否三数之和等于0,在此过程中,加入了去重的操作。原创 2023-11-25 23:13:14 · 136 阅读 · 0 评论 -
leetcode刷题日志-11盛最多水的容器
依题我们可知,容纳水量计算方式为 min(height[i] , height[j])* (j-i),进一步观察,若我们移动短板,则容纳水量可能增加,也可能减少,若我们移动长板,那么必定减少或者不变。故我们设置两个指针,分别指向头尾(使底最大),每次移动数值小的指针,最后便能找到最大容纳水量。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。说明:你不能倾斜容器。原创 2023-11-24 17:28:11 · 304 阅读 · 0 评论 -
leetcode刷题日志-70爬楼梯
经典的动态规划问题,假设有n级台阶,那么n级台阶的爬法肯定是n-1级的加n-2级爬法的。那么我们就要动态转移方程dp[i] = dp[i-1] + dp[i-2]每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?需要 n 阶你才能到达楼顶。:有两种方法可以爬到楼顶。:有三种方法可以爬到楼顶。原创 2023-11-23 17:16:59 · 82 阅读 · 0 评论 -
leetcode刷题日志-167.两数之和II-输入有序数组
这几个字眼很关键,题目是找两个数之和等于target的两个数的索引,而给定的数组是从小到大排列的,这说明数组从左到右是依次增大,从右到左是依次减小,并且target肯定存在,那么我们就可以设置两个指针,数组头尾各一个,如果头尾指针所指位置元素相加小于target,就将头指针往右移,反之,则将尾指针往左移,这样逼近target,如此就能在O(n)时间内解决。以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。返回 [1, 2]。原创 2023-11-23 16:39:06 · 161 阅读 · 0 评论 -
leetcode刷题日志-392判断子序列
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。t和s各设一个指针,遍历t字符串,每与s字符串元素匹配,s的指针+1,若遍历完t字符串,s的指针能走完整个s,则成功,否则失败。给定字符串 s 和 t ,判断 s 是否为 t 的子序列。输入:s = “abc”, t = “ahbgdc”输入:s = “axc”, t = “ahbgdc”两个字符串都只由小写字符组成。原创 2023-11-21 17:14:11 · 116 阅读 · 0 评论 -
leetcode刷题日志-125验证回文串
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。思路,字符串头尾各一个指针,遇到非字母数字的元素一直移动指针到字母或者数字元素,进行比较。:“amanaplanacanalpanama” 是回文串。:在移除非字母数字字符之后,s 是一个空字符串 “”。,返回 true;否则,返回 false。由于空字符串正着反着读都一样,所以是回文串。:“raceacar” 不是回文串。字母和数字都属于字母数字字符。给你一个字符串 s,如果它是。,中间有一个不能匹配返回。原创 2023-11-21 16:26:38 · 178 阅读 · 0 评论 -
leetcode刷题日志-68.文本左右对齐
给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。LeetCode的一道困难题,想了半天,写了好久代码,没跑出来,思路跟官方是一样的就是代码没实现,哎,又是。每个单词的长度大于 0,小于等于 maxWidth。文本的最后一行应为左对齐,且单词之间不插入。图一乐呵,来看看官方的,我的思路基本一致。原创 2023-11-19 23:36:00 · 221 阅读 · 0 评论 -
leetcode刷题日志-28.找出字符串中第一个匹配项的下标
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。我知道这道题可以用KMP算法,奈何太菜不会写,下去好好研究一下,只能用最朴素的解法,以每个字母为开头,遍历是否存在完全匹配的串。:“leeto” 没有在 “leetcode” 中出现,所以返回 -1。注:KMP算法的时间复杂度为O(m+n)。第一个匹配项的下标是 0 ,所以返回 0。:“sad” 在下标 0 和 6 处匹配。原创 2023-11-19 18:53:29 · 164 阅读 · 0 评论 -
leetcoe刷题日志-6N字形变换
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。这道题没想出来,看了题解。原创 2023-11-18 23:28:46 · 115 阅读 · 0 评论 -
leetcode刷题日志-151反转字符串中的单词
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。给你一个字符串 s ,请你反转字符串中 单词 的顺序。:反转后的字符串中不能存在前导空格和尾随空格。原创 2023-11-17 15:55:21 · 78 阅读 · 0 评论 -
leetcode刷题日志-14最长公共前缀
依题意,假设第一个元素为最大公共前缀,一次遍历,跟每一个单词进行比对,然后对最大公共前缀进行裁切,遍历完整个数组,剩下的就是最大公共前缀。可以看到,这个性能很一般,只超过了5.2%,我想想怎么优化一下。编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。代码效率有了很明显的提高。:输入不存在公共前缀。我们可以看到这段代码。原创 2023-11-17 15:31:05 · 665 阅读 · 0 评论 -
leetcode刷题日志-58最后一个单词的长度
刚开始很容易想到使用split()函数,将字符串按‘ ’分割成字符数组,直接返回最后一个单词长度即可,但是时间复杂度跟空间复杂度都比较高,于是想优化一波。根据题意,我们找最后一单词的长度,我们只需从后往前遍历,遇到第一个非’ ‘字符开始,到’ '字符结束的长度就是最后一个单词的长度。给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。解释:最后一个单词是长度为6的“joyboy”。解释:最后一个单词是“moon”,长度为4。:最后一个单词是“World”,长度为5。s 中至少存在一个单词。原创 2023-11-17 12:37:18 · 209 阅读 · 0 评论 -
leetcode刷题日志-13整数转罗马数字
数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4。解释: M = 1000, CM = 900, XC = 90, IV = 4.罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。思路:根据规则可知,我们可以从最大的罗马数字开始,让给定的整数依次除以罗马数字所代表的数,有几个则加入几个罗马符号,这里记得处理几种特殊情况。I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。原创 2023-11-17 00:00:15 · 173 阅读 · 0 评论 -
LeetCode刷题日志-135分发糖果
想了10分钟没想出来,刚开始的思路:一次遍历后面孩子比前面孩子大则糖果数为前面孩子糖果数+1,否则,将后面孩子设为为1,前面孩子在此基础上+1。n 个孩子站成一排。解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目。第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。题解思路:贪心策略,计算局部最优,获得全局最优。输入:ratings = [1,2,2]原创 2023-11-15 08:58:12 · 65 阅读 · 0 评论 -
leetcode刷题日志-除自身以外数组的乘积
我们可以观察分析,题目需要返回的answer数组中answer[i] 等于除nums[i] 外所有元素乘积,也就是nums[i]左半边乘积,与右半边乘积。给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。乍一看,题目很简单,两个循环就能解决,但是题目规定时间复杂度O(n),且不能有除法,难度就上升了。我们可以开一个数组,先记录左半边乘积,然后再开一个数组,计算右半边乘积,空间复杂度为O(n)原创 2023-11-12 13:03:47 · 71 阅读 · 0 评论 -
leetcode刷题日志-H指数
根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且每篇论文 至少 被引用 h 次。根据这句话的意思,就可以解决了“一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且每篇论文 至少 被引用 h 次”由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。原创 2023-11-11 17:33:10 · 98 阅读 · 0 评论 -
leetcode刷题日志-跳跃游戏2
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。输入: nums = [2,3,1,1,4]解释: 跳到最后一个位置的最小跳跃数是 2。输入: nums = [2,3,0,1,4]题目保证可以到达 nums[n-1]原创 2023-11-11 14:19:32 · 54 阅读 · 0 评论 -
Java实现个位数的统计
给定一个 k 位整数 N=dk−110k−1+⋯+d1101+d0 (0≤di≤9, i=0,⋯,k−1, dk−1>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定 N=100311,则有 2 个 0,3 个 1,和 1 个 3。输入格式:每个输入包含 1 个测试用例,即一个不超过 1000 位的正整数 N。输出格式:对 N 中每一种不同的个位数字,以 D:M 的格式在一行中输出该位数字 D 及其在 N 中出现的次数 M。要求按 D 的升原创 2020-11-22 14:45:31 · 754 阅读 · 2 评论 -
Java实现----连续座位号
每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。输入格式:输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证原创 2020-11-22 14:49:59 · 562 阅读 · 0 评论 -
2. 两数相加 (LeetCode )java实现;
题解原创 2023-03-27 21:34:26 · 204 阅读 · 0 评论 -
LeetCode刷题日志-跳跃游戏
没有考虑到找到这个元素之前能不能跳到这个元素(当有一个数组元素的值大于数组长度 - 数组下标时)。写博客时突然有个想法,如果我再把这个元素当作同样的问题递归一下,好像问题也能解决,一会儿试试。就是当前下标+当前下标下的元素数值,如果大于最大跳跃数就更新。直到最大跳跃数大于数组长度 - 1,返回true,否则返回false;解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。遍历一次,当有一个数组元素的值大于数组长度 - 数组下标时,返回true。原创 2023-11-09 16:47:58 · 42 阅读 · 0 评论 -
带权重的随机算法-告诉你游戏抽奖原理-代码+示例
带权重的随机算法(Weighted Random Algorithm)是一种在给定一组具有不同权重的选项时,根据权重随机选择一个选项的算法。这种算法常用于需要按照某种分布来选择元素的情况,比如负载均衡、随机化测试、游戏中的随机事件等。比如游戏抽奖,抽中最好奖品的概率会随着抽奖次数的增加而增加。以下我们来举一个学生点名的例子,用以理解带权重的随机算法。点名要求如下:1,最初每个学生被点到名的概率一样。2,每次被点到名下次再被点到的概率减半。姓名-性别-年龄-权重。下面为带权重的随机算法。原创 2023-08-16 14:19:42 · 1484 阅读 · 0 评论 -
动态规划实验 0-1背包问题 代码+流程图
1.实验内容0-1背包问题:若有物品n个,每个物品的价值Value,用vi表示,每个物品的重量weight用wi表示,其中vi和wi均为非负数。设背包的总容量为W,且W为非负数。现需要考虑的问题是:如何选择装入背包的物品,使装入背包的物品总价值最大。【动态规划解步骤】第一步,刻画问题的最优解子结构。可以将背包问题的求解过程看作是进行一系列的决策过程,即决定哪些物品应该放入背包,哪些物品不放入背包。如果一个问题的最优解包含了物品n,即xn=1,那么其余x1,x2,…,x(n-1)一定构成子问题1,2,…原创 2020-11-25 09:31:02 · 8911 阅读 · 0 评论