
算法与数据结构
文章平均质量分 74
every__day
这个作者很懒,什么都没留下…
展开
-
如何用 BitSet 求解质数问题
BitSet 的应用。在 ArrayList 的源码中,巧用BitSet 实现数组原地复制原创 2022-07-28 21:16:34 · 379 阅读 · 0 评论 -
BitSet源码解析,位运算玩的真六
BitSet 也就是位图,底层用 long 数组,用 位 来存储数据。本文介绍 BItSet 常用的方法,及源码解析原创 2022-07-20 23:20:41 · 2456 阅读 · 2 评论 -
双指针解决发饼干问题(leetcode455)
今天是圣诞节,正好遇到的一个发糖果的题目,也算是应景(leetcode455)。假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 示例 1:输入: g = [1,2,3], s原创 2020-12-25 20:21:32 · 195 阅读 · 0 评论 -
动态规划,小试牛刀——使用最小花费爬楼梯(leetcode 746)
数组的每个索引作为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 cost[i](索引从0开始)。每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。示例 1:输入: cost = [10, 15, 20]输出: 15解释: 最低花费是从cost[1]开始,然后走两步即可到阶梯顶,一共花费15。示例 2:输入: cost = [1, 100, .原创 2020-12-21 21:13:14 · 252 阅读 · 0 评论 -
写的让人伤心的翻转对(leetcode493)
给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。你需要返回给定数组中的重要翻转对的数量。示例 1:输入: [1,3,2,3,1]输出: 2示例 2:输入: [2,4,3,5,1]输出: 3注意:给定数组的长度不会超过50000。输入数组中的所有数字都在32位整数的表示范围内。看到这个题目,我没想到什么好的方法,老老实实的暴力破解吧初级版public int reverseP原创 2020-11-28 21:52:03 · 197 阅读 · 0 评论 -
桶排序的应用—— 有多少小于当前数字的数字(leetcode 1365)
看到题目,我没想到桶排序,想到的是暴力算法。给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。以数组形式返回答案。 示例 1:输入:nums = [8,1,2,2,3]输出:[4,0,1,1,3]解释: 对于 nums[0]=8 存在四个比它小的数字:(1,2,2 和 3)。 对于 num原创 2020-10-26 22:21:05 · 273 阅读 · 0 评论 -
从多张优惠券中,挑出合适组合,使其最接近手续费 —— 失效的贪心算法到改装的动态规划
背景最近在做基金的一个项目,后台会给客户发优惠券。用这些券可以抵扣买基金时的手续费。项目经理提出这么一个需求:客户有多张优惠券可使用,某次交易,手续费是确定的。系统自动给算出来,要使用哪几张券,客户最划算。规则有以下三条:半月内过期的券优先使用优先使用大额的优惠券优惠券充足时,选出的组要不低于手续费,尽可能接近。需求拆分人家项目经理给出的要求很合理,对客户来讲也很人性化。可这需求不太好实现,比较复杂,但对于非常合理的需要,合格的程序员,理应努力实现其需求。于是乎,开始和同事讨论方案原创 2020-10-11 10:50:55 · 2872 阅读 · 6 评论 -
leetcode 235. 二叉搜索树的最近公共祖先
二叉搜索树,是常见的树形结构,其搜索效率比较高。如果对二叉搜索树不熟悉,可以看之前的博客:二叉搜索树下面看一道二叉搜索树的算法题目,leetcode地址给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树:如上图 root = [6,2,8,0,4,7,9,null,nul原创 2020-09-27 20:27:44 · 361 阅读 · 0 评论 -
写不出来的深度优先搜索----leetcode113 路径总和
一道简单的深度优先搜索的题目:leetcode给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。说明: 叶子节点是指没有子节点的节点。示例:给定如下二叉树,以及目标和 sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1返回:原创 2020-09-26 14:16:12 · 224 阅读 · 0 评论 -
PriorityQueue --前K个高频元素 leetcode347
java 中 PriorityQueue 是用堆来实现的,今天就遇到了用堆来解决的算法题目:leetcode给定一个非空的整数数组,返回其中出现频率前 k 高的元素。示例 1:输入: nums = [1,1,1,2,2,3], k = 2输出: [1,2]示例 2:输入: nums = [1], k = 1输出: [1] 提示:你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小原创 2020-09-07 21:51:57 · 304 阅读 · 0 评论 -
一想就会,一写就废——leetcode 557 反转字符串
反转字符串,挺简单的代码,写出来一次以一次的不通过。leetCode地址给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。示例:输入:"Let's take LeetCode contest"输出:"s'teL ekat edoCteeL tsetnoc" 提示:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。很简单的一道题目,我最初的思路是扫描字符串,遇到一个空格,就把前面的单词抽取出来,反转,再拼接。代码如下: p原创 2020-08-30 11:14:54 · 260 阅读 · 0 评论 -
看不懂的dfs——leetcode 491递增子序列
遇到一个看不懂题解的题,leetcode地址给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。示例:输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]说明:给定数组的长度不会超过15。数组中的整数范围是 [-100,100]。给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。这个题目我理解的原创 2020-08-25 21:00:26 · 307 阅读 · 0 评论 -
leetcode 201:数字范围按位与 —— 想不到的位运算
遇到一个很套路的题目,leetcode题目地址。给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。示例 1: 输入: [5,7]输出: 4示例 2:输入: [0,1]输出: 0我首先想到的,直接位运算 public int rangeBitwiseAnd(int m, int n) { int temp = m; int result原创 2020-08-23 11:56:35 · 429 阅读 · 0 评论 -
Leetcode 546移除盒子:难以想通的动态规划
动态规划,是出了名的难。今天遇到的这个题目,动态转移方程,看半天,还是看不懂,写篇文章记录下。题目链接添加链接描述给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色。你将经过若干轮操作去去掉盒子,直到所有的盒子都去掉为止。每一轮你可以移除具有相同颜色的连续 k 个盒子(k >= 1),这样一轮之后你将得到 k*k 个积分。当你将所有盒子都去掉之后,求你能获得的最大积分和。示例:输入:boxes = [1,3,2,2,2,3,4,3,1]输出:23解释:[1,原创 2020-08-15 17:18:42 · 383 阅读 · 0 评论 -
leetcode-130. 被围绕的区域---广度优先算法与深度优先算法
再次遇到 广度优先算法和深度优先算法。leetcode地址给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。示例:X X X XX O O XX X O XX O X X运行你的函数后,矩阵变为:X X X XX X X XX X X XX O X X解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O原创 2020-08-11 23:14:04 · 385 阅读 · 0 评论 -
让人头疼的回文对(leetcode 336)
今天遇到算法bug,查错用了好久。添加链接描述给定一组 互不相同 的单词, 找出所有不同 的索引对(i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。示例 1:输入:["abcd","dcba","lls","s","sssll"]输出:[[0,1],[1,0],[3,2],[2,4]] 解释:可拼接成的回文串为 ["dcbaabcd","abcddcba","slls","llssssll"]示例 2:输入:["bat","tab","原创 2020-08-06 23:24:14 · 283 阅读 · 0 评论 -
Leetcode 104 二叉树的最大深度
二叉树的最大深度,这个题目可用递归来解决,原题地址添加链接描述给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7返回它的最大深度 3 这个题目,可用递归来解决,也可以用广度优先搜索,这里以递归为例来说明,广度优先搜索,可参考这篇文章。广度优先算法/** * De原创 2020-07-28 21:25:50 · 201 阅读 · 0 评论 -
用双指针,判断子序列
历次做算法题目,今天耗时最短。题目原链接leetcode给定字符串 s 和 t ,判断 s 是否为 t 的子序列。你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。示例 1:s = "abc", t = "ahbgdc"返回 tr原创 2020-07-27 21:24:26 · 288 阅读 · 0 评论 -
用深度优先搜索解决最长路径问题
这道题目是困难级别的,原题目地址leetcode,我刚开始没想出头绪,看了题解,才想到用深度优先搜索,仅此而已给定一个整数矩阵,找出最长递增路径的长度。对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。示例 1:输入: nums = [ [9,9,4], [6,6,8], [2,1,1]] 输出: 4 解释: 最长递增路径为 [1, 2, 6, 9]。示例 2:输入: nums = [ [3,4,5],原创 2020-07-26 17:56:19 · 2590 阅读 · 0 评论 -
缺失的正整数——不考算法,考脑力
缺失的正整数,我自己解出来了,和官方题解思路不一样题目描述:给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。示例 1输入: [1,2,0]输出: 3示例 2:输入: [3,4,-1,1]输出: 2示例 3:输入: [7,8,9,11,12]输出: 1 提示:你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。我的思路很直接,排序之后,重复的去重,剩下的第一个元素与1比较,第二个元素与2比较,第三个元素与3比较,依次类推,只原创 2020-06-27 21:31:00 · 521 阅读 · 2 评论 -
用动态规划,解决单词拆分
动态规划是出了名的不好理解,今天遇到的这个题,我怎么也想不到可以用动态规划来解决。原题目链接描述:给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明:拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。示例 1:输入: s = "leetcode", wordDict = ["leet", "code"]输出: true解释: 返回 true 因为 "leetcode" 可以被拆分成 "原创 2020-06-25 11:34:06 · 497 阅读 · 0 评论 -
最长的序列
今天遇到一个比较容易的题,leetCode地址给定一个未排序的整数数组,找出最长连续序列的长度。要求算法的时间复杂度为 O(n)。示例:输入: [100, 4, 200, 1, 3, 2]输出: 4解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。我想到的是先排序,再遍历排序后的数组。排序O(logn)的算法,比如归并排序或快排,算法详情地址。遍历数组,时间复杂度为O(n)。官方题解给了另外一种思路 public int longestConsecutive(i原创 2020-06-06 21:20:09 · 541 阅读 · 0 评论 -
自然数 前n项和——当你不能用循环时,怎么办
遇到一个限制型题目,挺有意思的。leetCode地址求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。 示例 1:输入: n = 3输出: 6示例 2:输入: n = 9输出: 45 限制:1 <= n <= 10000当遇到一个十分简单的题目,可你想到的工具都不让你用,那就是急的干瞪眼,就是 巧妇难为无米之炊我能想到用递归,可递归退出的条件,不还得用 if 么原创 2020-06-02 23:04:40 · 419 阅读 · 0 评论 -
最大矩形——暴力解法也可以
public int largestRectangleArea(int[] heights) { if(null == heights || heights.length == 0) return 0; int res = 0; int n = heights.length; for(int i = 0; i < n; i++){ int left = i, h = heights[i], right = i;原创 2020-05-31 20:58:54 · 484 阅读 · 0 评论 -
打家劫舍——简单的动态规划,为什么我实现的如此复杂
今天遇上的是典型的动态规划问题,只是我实现的不够优雅。leetCode原题地址你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。示例 1:输入: [1,2,3,1]输出: 4解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 =原创 2020-05-29 23:23:57 · 259 阅读 · 0 评论 -
和可被 K 整除的子数组——前缀和居然超时了
今天又一次倒在了前缀和上,leetCode原题给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。示例:输入:A = [4,5,0,-2,-3,1], K = 5输出:7解释:有 7 个子数组满足其元素之和可被 K = 5 整除:[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] 提示:1 <= A.length <= 30000-1000原创 2020-05-27 23:35:57 · 264 阅读 · 0 评论 -
LRU缓存机制——简化版的LinkedHashMap
今天是个综合的题目,实现LRU。原题目地址:leetcode运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。写入数据 put(key, value) - 如果密钥已经存在,则变更其数据值;如果密钥不存在,则插入该组「密钥/数据值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值原创 2020-05-25 23:28:02 · 267 阅读 · 1 评论 -
从前序与中序遍历序列构造二叉树——疯狂递归吧
二叉树的遍历是递归来实现,两样反向构建二叉树,也是用递归实现。原题链接根据一棵树的前序遍历与中序遍历构造二叉树。注意:你可以假设树中没有重复的元素。例如,给出前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7]返回如下的二叉树: 3 / \ 9 20 / \ 15 7二叉树的基础和三种遍历方式,请看这篇文章:前序遍历、中序遍历和后序遍历直接上代码,用代码解释更明了。 M原创 2020-05-22 23:29:12 · 321 阅读 · 0 评论 -
每个元音包含偶数次的最长子字符串——打死我也想不到的代码
这道题目,官方给出的题解,打死我也想不到。原题目地址给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 'a','e','i','o','u' ,在子字符串中都恰好出现了偶数次。示例 1:输入:s = "eleetminicoworoep"输出:13解释:最长子字符串是 "leetminicowor" ,它包含 e,i,o 各 2 个,以及 0 个 a,u 。示例 2:输入:s = "leetcodeisgreat"输出:5解释:最长子字符串是 "leet原创 2020-05-21 22:41:21 · 854 阅读 · 0 评论 -
加强版的回文字符串
回文字符串很容易理解,这道题目是加强版的回文验证。原题目地址给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。示例 1:输入: "aba"输出: True示例 2:输入: "abca"输出: True解释: 你可以删除c字符。这个递归来求解 public boolean validPalindrome(String s) { if(null == s) return false; int len = s.length();原创 2020-05-19 22:42:50 · 264 阅读 · 0 评论 -
课程表——图的应用
今天这题目,是经典的图的遍历问题。现在你总共有 n 门课需要选,记为 0 到 n-1。在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。示例 1:输入: 2, [[1,0]] 输出: [0,1]解释: 总共有 2 门课程。要学习课程 1,你需要先完成课原创 2020-05-17 17:39:19 · 612 阅读 · 0 评论 -
和为K的子数组,想不到的,就是想不到。
今天遇到这个,只想到了暴力破解。leetcode给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。示例 1 :输入:nums = [1,1,1], k = 2输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。我想到的是暴力破解,见代码,外层遍历数组,内层以该元素为结尾,累加之前的,和为k,结果加1。这样不会重也不会漏。 public int subarraySum(int[] nums, int k) { int res = 0原创 2020-05-15 23:07:58 · 459 阅读 · 0 评论 -
二叉树的层级遍历,居然可以用递归
看这么一道题目,取自leetcode给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。示例:二叉树:[3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其层次遍历结果:[ [3], [9,20], [15,7]]我想到的方法,是用栈来实现,把一层的结果同时入栈,再同时出栈,完成题目的要求,具体看代码。 public List<Lis原创 2020-05-13 23:13:53 · 713 阅读 · 0 评论 -
int边界值会惹祸——求一个数的n次方(Pow(x, n))
今天遇到一个int边界值报错的题目,特地记录一下。 原题目:链接实现 pow(x, n) ,即计算 x 的 n 次方函数。示例 1:输入: 2.00000, 10输出: 1024.00000示例 2:输入: 2.10000, 3输出: 9.26100示例 3:输入: 2.00000, -2输出: 0.25000解释: 2-2 = 1/22 = 1/4 = 0.25说明:-100.0 < x < 100.0n 是 32 位有符号整数,其数值范围是 [−2^31原创 2020-05-11 22:17:33 · 380 阅读 · 0 评论 -
只能暴力破解“最大正方形”么?
暴力破解是最容易想到的,比如这个leetcode题目。添加链接描述在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。示例:输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4题目很好理解。我首先想到的是暴力破解,思路是遍历二维数组,遇到1时,就在此基础上逐层往外扩展,直到达到边界,或者扩展过程中遇到0。 public int maximalSquare(char[][] matrix) {原创 2020-05-08 18:21:34 · 265 阅读 · 0 评论 -
递归中的递归——另一个树的子树
递归中的递归,今天来看下这么一道题,这里可以看原题目的链接:leetcode给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。示例 1:给定的树 s: 3 / \ 4 5 / \ 1 2给定的树 t: 4 ...原创 2020-05-07 14:19:34 · 346 阅读 · 0 评论 -
让人费解的动态规划——最低票价
今天遇到的这道题,我知道要用动态规划,可就是想不出状态转移方程。看了题解,才明白,它倒序求得的。题目链接如下:leetcode,最低票价在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。火车票有三种不同的销售方式:一张为期一天的通行证售价为 costs[0] 美元;一...原创 2020-05-06 23:56:29 · 547 阅读 · 0 评论 -
用中序遍历和递归,验证二叉搜索树
之前的文章,介绍过二叉树的遍历问题,也介绍过递归,今天看看用它是怎么解决算法题目的二叉树遍历,递归的实现这还是leetCode上的一道题,链接如下:验证二叉搜索树给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:1、节点的左子树只包含小于当前节点的数。2、节点的右子树只包含大于当前节点的数。3、所有左子树和右子树自身必须也是二叉搜索树。示例 1:...原创 2020-05-05 15:51:39 · 849 阅读 · 0 评论 -
动态规划来解决“最大子序和”
动态规划,在算法与数据结构中,是最难掌握的知识点之一。没有别的捷径,理解其算法思想后,就是多练,写的多了,就知道怎么写了。这是leetCode的一道题,来看来动态规划的运用。原题目链接给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例:输入: [-2,1,-3,4,-1,2,1,-5,4],输出: 6解释: 连续子数组 [4,-...原创 2020-05-03 18:52:09 · 286 阅读 · 0 评论 -
"快乐数字"的计算
这道leetcode题目,官方的题解,代码特别优雅。自己写的很粗糙,记录下官方的题解。题目叙述编写一个算法来判断一个数 n 是不是快乐数。「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。如果 n 是快乐数就返回 True ;不是,则返回 F...原创 2020-04-30 12:48:46 · 751 阅读 · 0 评论