算法刷题
文章平均质量分 92
题目都来自于Leetcode和Niuke
编程初学者z
这个作者很懒,什么都没留下…
展开
-
笔试真题
1.华为笔试第3题题目描述:假如有1米和2米的线段若干,现需要拼接成4米的线段,一共有1+1+1+1,1+1+2,2+2, 3种拼接方法。现在需要拼接m米线段,有C1,C2,C3,…线段可供选择,一共有多少种拼接方法。输入:4 1 2 输入描述:第一个值为需要拼接的线段长度,后面的值为可供选择的线段长度输出:3解题思路:看到该题,和上一题有点类似,有点类似于硬币找零的问题,求一共有多少种找零的方法。首先能想到的就是采用回溯法,列举出所有的可能,但是如果m很大的话时间复杂度太高了。我们可以采用原创 2020-07-16 16:45:22 · 446 阅读 · 0 评论 -
博弈论
我们通常会遇到关于博弈论类似的题目,本文总结了刷题过程中该类型的题目。1. leetcode 292.NIM游戏题目描述:你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。解题思路:由于每次A和B每个人最多能拿3块石头,那么只要满足一个条件即可获胜:A拿了1-3块石头中,只要有一种情况下B都使无法获胜,那么A一定原创 2020-07-11 21:00:17 · 310 阅读 · 0 评论 -
LRU缓存机制算法实现
一、什么是 LRU 算法就是一种缓存淘汰策略。计算机的缓存容量有限,如果缓存满了就要删除一些内容,给新内容腾位置。但问题是,删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存,而把有用的数据继续留在缓存里,方便之后继续使用。那么,什么样的数据,我们判定为「有用的」的数据呢?LRU 缓存淘汰算法就是一种常用策略。LRU 的全称是 Least Recently Used,也就是说我们认为最近使用过的数据应该是是「有用的」,很久都没用过的数据应该是无用的,内存满了就优先删那些很久没用过的数据。二、LRU缓原创 2020-05-21 17:32:58 · 402 阅读 · 0 评论 -
leetcode 136. 只出现一次的数字
题目描述:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?解题思路:方法一:看到该题,第一想法就是采用hashmap的方法去统计每个数字出现的次数。但是由于要求时间复杂度为线性,空间复杂度为O(1),所以哈希表的方法不行。方法二:(错误的方法)其次想到这和以前的一个题目类似,在数组中寻找唯一重复的那个元素。但是由于数组元素的范围是无法确定的,所以无法采用循环排序的思原创 2020-05-20 17:58:30 · 177 阅读 · 0 评论 -
leetcode 101. 判断对称二叉树
题目描述:给定一个二叉树,检查它是否是镜像对称的。例如,二叉树 [1,2,2,3,4,4,3] 是对称的。解题思路:如果我们将1看作根节点root,镜像对称需要满足,root.left的左节点和root.right的右节点相同;并且root.left的右节点和root.right的左节点相同(1)所以我们需要两颗一样的树root来进行遍历。(2)判断递归结束条件,当两颗树有一个为null,返回false(2)比较isSame(root1.left, root2.right)和isSame(r原创 2020-05-19 16:22:32 · 151 阅读 · 0 评论 -
leetcode 105. 从前序与中序遍历序列构造二叉树
题目描述:根据一棵树的前序遍历与中序遍历构造二叉树。注意:你可以假设树中没有重复的元素。例如,给出解题思路:通过前序遍历我们可以确定出根节点就是preorder[0],通过中序遍历可以确定出左右子树,再依次递归(1)确定递归结束条件:如果当前子树为null,则返回空(2)通过preorder找到根节点preorder[0],去中序遍历中查找根节点的位置。(3)找到该位置,再递归遍历,给根节点root添加左右子树代码: public TreeNode buildTree(int[原创 2020-05-19 16:02:48 · 190 阅读 · 0 评论 -
leetcode 79. 在二维网格内搜索单词
题目描述:给定一个二维网格和一个单词,找出该单词是否存在于网格中。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。解题思路:由于我们要在二维数组中寻找路径,所以我们可以采用递归的方式,如果当前路径不符合要求,我们进行回退,所以采用回溯法。(1)我们首先遍历数组,确定一个路径开始的位置(2)重写一个函数isExist,来判断重该位置board[i][j]开始走,是否能够找到一条路径(3)isExist原创 2020-05-14 15:39:54 · 1803 阅读 · 0 评论 -
leetcode 50. 实现方法Pow(x, n)
题目描述:实现 pow(x, n) ,即计算 x 的 n 次幂函数。解题思路:该题目首先想到就是采用暴力解决的方法,依次乘起来,不过时间复杂度为O(n),并且由于计算的是乘法,所以开销很大。所以会超出时间限制我们可以换一个思路,采用分治的思想,这样时间复杂度就降到了logn ,只需要不断计算x^(n/2)就行了。x^n = x^(n/2) * x^(n/2)如果采用递归来计算,也就是直接采用自顶向下递归,存在冗余计算,x^(n/2)只需要计算一次即可。所以我们需要自底向上的计算方式,可以采原创 2020-05-11 10:41:45 · 349 阅读 · 0 评论 -
leetcode 75. 颜色分类
题目描述:给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。注意:不能使用代码库中的排序函数来解决这道题。解题思路:初始想法就是排序就能解决了,但是题目要求需要常数空间和一趟扫描。所以就想到可以使用快速排序的思想,将大于1的放左边,小于1的放右边就可以了。也就是采用双指针,左右指针,当左指针的值大于1,右指针的值小于1,交换这两个数。比如:[2,原创 2020-05-10 15:12:45 · 298 阅读 · 0 评论 -
leetcode 62. 有多少条不同路径
题目描述:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径?解题思路:方法一:动态规划。由于当前的路径数量与前一个路径数是有关系的所以采用动态规划。1.状态定义:我们定义dp[i][j]为网格i,j位置的路径数量2.状态转移方程:当前位置是由左边和上边移动而来的,因为每次只能向下或者向右移动一步。所以是dp[i-1][j]和dp[原创 2020-05-09 11:15:53 · 591 阅读 · 0 评论 -
leetcode 33. 搜索旋转排序数组
leetcode 33. 搜索旋转排序数组题目描述:假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是 O(log n) 级别。解题步骤:看到该...原创 2020-05-06 10:45:10 · 220 阅读 · 0 评论 -
leetcode 518. 零钱兑换 II
题目描述:给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。输入: amount = 5, coins = [1, 2, 5]输出: 4解释: 有四种方式可以凑成总金额:5=55=2+2+15=2+1+1+15=1+1+1+1+1解题步骤:题目就是找到所有数组中的组合使其和等于target,初步一想回溯法遍历所有的路径就能找...原创 2020-04-29 10:59:38 · 319 阅读 · 0 评论 -
回溯算法详解
回溯算法详解一、回溯算法框架二、全排列问题三、N皇后问题四、子集问题五、总结一、回溯算法框架解决一个回溯问题,实际上就是一个决策树的遍历过程。你只需要思考 3 个问题:路径:也就是已经做出的选择。选择列表:也就是你当前可以做的选择。结束条件:也就是到达决策树底层,无法再做选择的条件。回溯算法框架代码:result = []def backtrack(路径, 选择列表...原创 2020-04-25 11:17:05 · 2614 阅读 · 0 评论 -
leetcode 90. 包含重复元素数组的所有子集
题目描述:给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。解题步骤:该题目和寻找数组元素所有子集类似,只是需要加上一个去重条件。方法一:采用BFS思路:如果前后两个数不重复,就直接加入所有元素乘积,并记录下添加该元素之前的alllist长度,比如在第3行,1和2不重复,此时的需要新添加的元素长度newAddLen为 ...原创 2020-04-24 11:34:53 · 517 阅读 · 0 评论 -
leetcode 78.不含重复元素数组的子集
题目描述:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。解题步骤:方法一:采用广度优先遍历BFS,从空集开始比如:代码: public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> alllis...原创 2020-04-23 11:24:41 · 918 阅读 · 0 评论 -
leetcode 113.路径总和为target的所有路径
题目描述:给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。说明: 叶子节点是指没有子节点的节点。解题步骤:方法一:采用迭代遍历的方式,通过栈数据结构,和leetcode 112.判断树中是否存在target的路径和 类似,所以就不写了方法二:采用递归的方式,用List来保存中间的节点,方法比较简单,但是时间复杂度较高代码: public Li...原创 2020-04-22 15:21:14 · 399 阅读 · 0 评论 -
leetcode 257. 遍历二叉树的所有路径
题目描述:给定一个二叉树,返回所有从根节点到叶子节点的路径。说明: 叶子节点是指没有子节点的节点。解题步骤:方法一:采用栈数据结构,先添加右子节点再添加左子节点。记录下当前节点和路径 public List<String> binaryTreePaths(TreeNode root) { Stack<TreeNode> node = new...原创 2020-04-22 11:35:38 · 972 阅读 · 0 评论 -
leetcode 112.判断树中是否存在target的路径和
题目描述:给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。说明: 叶子节点是指没有子节点的节点。解题步骤:方法一:采用栈数据结构,来依次遍历每个节点,并保持每条路径的总和代码: public boolean hasPathSum(TreeNode root, int sum) { if(root==null) ret...原创 2020-04-22 11:22:36 · 428 阅读 · 0 评论 -
leetcode 111. 二叉树的最小深度
题目描述:给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明: 叶子节点是指没有子节点的节点。解题步骤:解法一:按照最初的想法,还是可以用宽搜BFS的方法来解决。(1)创建一个队列用来保存每一层的节点(2)如果遍历到当前节点的左右子节点都为空,返回当前的层数,就是二叉树的最小深度代码: public int minDepth(Tr...原创 2020-04-21 12:11:56 · 295 阅读 · 1 评论 -
leetcode 11. 盛最多水的容器
题目描述:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器,且 n 的值至少为 2。输入:[1,8,6,2,5,4,8,3,7]输出:49解题步骤:该题目可以采用双指针...原创 2020-04-19 11:28:43 · 293 阅读 · 0 评论 -
leetcode 25. K 个一组翻转链表
题目描述:给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。给你这个链表:1->2->3->4->5当 k = 2 时,应当返回: 2->1->4->3->5当 k = 3 时,应当返回: 3->2->...原创 2020-04-19 11:09:52 · 215 阅读 · 0 评论 -
leetcode 92. 反转链表 II
题目描述:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。说明:1 ≤ m ≤ n ≤ 链表长度。输入: 1->2->3->4->5->NULL, m = 2, n = 4输出: 1->4->3->2->5->NULL解题步骤:定位到要反转部分的头节点 2,head = 2;前驱结点 1,pre = 1;当前节点...原创 2020-04-19 10:30:43 · 274 阅读 · 0 评论 -
lectcode 287. 寻找重复数
题目描述:给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。说明:不能更改原数组(假设数组是只读的)。只能使用额外的 O(1) 的空间。时间复杂度小于 O(n2) 。数组中只有一个重复的数字,但它可能不止重复出现一次。解题步骤:该题要求可时间复杂度和空间复杂度,初...原创 2020-04-17 11:34:30 · 327 阅读 · 0 评论 -
leetcode 448. 找到所有数组中消失的数字
题目描述:给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。找到所有在 [1, n] 范围之间没有出现在数组中的数字。您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。解题步骤:由于要求不能使用额外空间并且时间复杂度为O(n),所以不能采用HashSet...原创 2020-04-17 11:03:19 · 132 阅读 · 0 评论 -
leetcode 19. 删除链表的倒数第N个节点
题目描述:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。给定一个链表: 1->2->3->4->5, 和 n = 2.当删除了倒数第二个节点后,链表变为 1->2->3->5.解题步骤:该题既要找打倒数第n个节点,又要删除该节点,采用快慢指针法。(1)快慢指针都指向head(2)快指针向前移动n-1个节点,如果快指针出现n...原创 2020-04-15 11:11:43 · 331 阅读 · 0 评论 -
leetcode 32. 最长有效括号
题目描述:给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。输入: “)()())”输出: 4解释: 最长有效括号子串为 “()()”解题步骤:该题首先先到可以采用动态规划求解。除此之外,还可以使用堆栈法来求解,通过栈数据结构来保存数据。(1)栈stack保存字符(2)栈pos保存字符在字符串中的索引位置(3)当字符加入到stack时,索引位置也加...原创 2020-04-15 10:47:35 · 377 阅读 · 0 评论 -
leetcode844. 比较含退格的字符串
题目描述:给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。解题步骤:采用栈数据结构来解题,如果栈为空,直接将字符放进栈中,如果当前字符为 # ,则弹出栈顶元素代码: public boolean backspaceCompare(String S, String T) { return ret(S...原创 2020-04-15 10:17:19 · 357 阅读 · 0 评论 -
leetcode 28 实现 strStr()
leetcode 28. 实现strStr题目描述:给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。输入: haystack = “hello”, needle = “ll”输出: 2解题步骤:这就是典型的字符串匹配的KMP算法。解题步骤如图所示:...原创 2020-04-15 10:10:57 · 264 阅读 · 0 评论 -
leetcode 1.多个数之和
leetcode 多个数之和1.两数之和1.两数之和题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 +...原创 2020-04-15 10:09:50 · 661 阅读 · 0 评论 -
leetcode 713. 乘积小于K的子数组
题目描述:给定一个正整数数组 nums。找出该数组内乘积小于 k 的连续的子数组的个数。输入: nums = [10,5,2,6], k = 100输出: 8解释: 8个乘积小于100的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], [2,6], [5,2,6]。需要注意的是 [10,5,2] 并不是乘积小于100的子数组。解题步骤:该题可以...原创 2020-04-12 16:10:04 · 359 阅读 · 0 评论 -
leetcode 340 最多带有K个不同字符的最长子字符串
leetcode 340 最多带有K个不同字符的最长子字符串题目描述:最多带有K个不同字符的最长子字符串,子字符串不能含有重复字符输入:5 ,“leetcode” 输出:5—“tcode”解题步骤:采用窗口长度可变的滑动窗口法。先让一个指针指向最左边i=0,依次移动右边指针至i=s.length()。如果当前字符不包含在子字符串,则将该字符添加进子字符串。反之,如果子串包含该字符,左...原创 2020-04-10 11:41:48 · 1038 阅读 · 0 评论 -
剑指Offer 机器人的运动范围
剑指Offer 机器人的运动范围题目描述:地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?解题步骤...原创 2020-04-09 11:46:28 · 235 阅读 · 0 评论 -
剑指Offer 矩阵中的路径
剑指Offer 矩阵中的路径题目描述:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个...原创 2020-04-09 11:18:45 · 275 阅读 · 0 评论 -
剑指Offer 数据流中的中位数
剑指Offer 数据流中的中位数题目描述:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。解题步骤:看到该题首先想到的是采用插入排序的方式,Insert()方...原创 2020-04-09 10:21:53 · 250 阅读 · 0 评论 -
剑指Offer 删除链表中重复的结点
剑指Offer 删除链表中重复的结点题目描述:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5解题步骤:由于要删除重复节点,所以我们在这里要设置三个节点:前置节点:pre 用来保存不重复的节点当前节点:cur 用来保...原创 2020-04-07 11:24:26 · 371 阅读 · 0 评论 -
剑指Offer 把字符串转换成整数
剑指Offer 把字符串转换成整数题目描述:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。输入描述:输入一个字符串,包括数字字母符号,可以为空输出描述:如果是合法的数值表达则返回该数字,否则返回0解题步骤:我们可以遍历字符串,得到每个字符的值再依次加起来就可以得到整个整数了sum = sum*10 + num。(1...原创 2020-04-06 11:33:07 · 221 阅读 · 0 评论 -
剑指Offer 不用加减乘除做加法
剑指Offer 不用加减乘除做加法题目描述:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。解题步骤:由于题目限定了无法使用加减乘除来计算两个数之和,所以我们采用二进制来计算两数之和。对于两数之和,我们必须计算出其进位 与 和才能计算出两数之和。对于进位我们直接对两个数进行按位与运算 & 就能计算出,还需向右移动1位。对于 求和我们可以采用按位异或 ...原创 2020-04-06 11:04:21 · 163 阅读 · 0 评论 -
剑指Offer 求1+2+3+...+n
剑指Offer 求1+2+3+...+n题目描述:求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。解题步骤:该题有许多限制:(1)不能使用乘除法,所以无法采用等差序列求和(2)不能使用for和while循环(3)不能使用if和else,无法判断循环结束条件所以常规的解题方法无法实现,我们可以采用...原创 2020-04-06 10:47:26 · 236 阅读 · 0 评论 -
剑指Offer 扑克牌顺子
剑指Offer 扑克牌顺子题目描述:LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q...原创 2020-04-05 21:47:33 · 252 阅读 · 0 评论 -
剑指Offer 两数之和
剑指Offer 两数之和题目描述:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。解题步骤:由于是从排好序的数组中找到两数之和,所以我们采用双指针法代码: public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) { A...原创 2020-04-05 12:23:38 · 429 阅读 · 0 评论