LintCode-Python题解
文章平均质量分 73
用最简单清晰的逻辑讲解lintcode题目和其相关算法。语言方面,选择了最易读的Python
guoziqing506
这个作者很懒,什么都没留下…
展开
-
lintcode - Reach a Number
题目描述:我简单将题目用汉语描述一下。说初始位置在0,给定一个目标值target(target是一个整数),现在让你每次走一步,每次走的步长和已经走的步数相等(第一次走1,第二次走2,。。。),每次可以向左或者向右走(也就是加正数或者负数),问最少走多少次可以走到target.解题思路:一开始想到的自然是广度优先搜索,但是我的运行时间出了问题。所以想到要优化算法。其实就我目前接触的算法而言...原创 2018-04-09 21:38:32 · 519 阅读 · 2 评论 -
lintcode - 循环单词
题目描述:The words are same rotate words if rotate the word to the right by loop, and get another. Count how many different rotate word sets in dictionary.E.g. picture and turepic are same rotate words....原创 2018-03-21 17:08:05 · 400 阅读 · 2 评论 -
lintcode - 加油站
题目描述:在一条环路上有 N 个加油站,其中第 i 个加油站有汽油gas[i],并且从第_i_个加油站前往第_i_+1个加油站需要消耗汽油cost[i]。你有一辆油箱容量无限大的汽车,现在要从某一个加油站出发绕环路一周,一开始油箱为空。求可环绕环路一周时出发的加油站的编号,若不存在环绕一周的方案,则返回-1。样例:现在有4个加油站,汽油量gas[i]=[1, 1, 3, 1],环路旅行时消耗的原创 2016-05-20 09:34:20 · 551 阅读 · 0 评论 -
lintcode - 中序遍历和后序遍历树构造二叉树
题目描述:根据中序遍历和后序遍历树构造二叉树这是典型的递归算法的应用。什么是中序遍历、后序遍历,我想无需多说了。直接看看遍历之后列表的结构。中序遍历:[left subtree, root, right subtree]后序遍历:[left subtree,right subtree, root]其中,每种遍历中的左右子树,也是按照同样的遍历模式原创 2016-10-24 17:50:41 · 1592 阅读 · 0 评论 -
lintcode - 插入区间
题目描述给出一个无重叠的按照区间起始端点排序的区间列表。在列表中插入一个新的区间,你要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。样例插入区间[2, 5] 到 [[1,2], [5,9]],我们得到 [[1,9]]。插入区间[3, 4] 到 [[1,2], [5,9]],我们得到 [[1,2], [3,4], [5,9]]。解题思路这道题所涉原创 2018-01-12 16:02:19 · 594 阅读 · 0 评论 -
lintcode - 把二叉搜索树转化成更大的树
题目描述:给定二叉搜索树(BST),将其转换为更大的树,使原始BST上每个节点的值都更改为在原始树中大于等于该节点值的节点值之和(包括该节点)。样例: Given a binary search Tree `{5,2,13}`: 5 / \ 2 13Return the root of new tree ...原创 2018-03-20 13:36:24 · 417 阅读 · 0 评论 -
lintcode - 堆化
题目描述:给出一个整数数组,堆化操作就是把它变成一个最小堆数组。对于堆数组A,A[0]是堆的根,并对于每个A[i],A [i * 2 + 1]是A[i]的左儿子并且A[i * 2 + 2]是A[i]的右儿子。样例:给出 [3,2,1,4,5],返回[1,2,3,4,5] 或者任何一个合法的堆数组有关堆数组的实现,我在另一篇博文中有详细的论述:堆的实现与优先队列。所以,讲解此处略,只原创 2016-09-17 18:39:53 · 857 阅读 · 0 评论 -
lintcode - 有效的括号序列
题目描述:给定一个字符串所表示的括号序列,包含以下字符: '(', ')', '{', '}', '[' and ']', 判定是否是有效的括号序列。样例:括号必须依照 "()" 顺序表示, "()[]{}" 是有效的括号,但 "([)]"则是无效的括号。其实题目的意思没有表达的很清楚,所谓“有效的”括号序列,指的是“非交错”的括号序列,也就是说,只有两种可能性是合法的:1.原创 2016-09-09 15:24:46 · 2161 阅读 · 0 评论 -
lintcode - 用栈模拟汉诺塔问题
题目描述:在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子。要求盘子必须按照从小到大的顺序从上往下堆 (如,任意一个盘子,其必须堆在比它大的盘子上面)。同时,你必须满足以下限制条件:(1) 每次只能移动一个盘子。(2) 每个盘子从堆的顶部被移动后,只能置放于下一个堆中。(3) 每个盘子只能放在比它大的盘子上面。请写一段程序,实现将第一个原创 2016-09-09 11:21:20 · 1764 阅读 · 0 评论 -
lintcode - 买卖股票的最佳时机 III
题目描述:假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。样例:给出一个样例数组 [4,4,6,1,1,4,2,5], 返回 6之前,关于“买卖股票”的故事,我们已经讲过两集:买卖股票的最佳时机,买卖股票的最佳时机 II。我默认你看这篇文章的时候,已经对前面两道题的方法彻底明白了。前面的第一道题关键是只能进行原创 2016-09-08 09:57:10 · 1872 阅读 · 0 评论 -
lintcode - 最接近的三数之和
题目描述:给一个包含 n 个整数的数组 S, 找到和与给定整数 target 最接近的三元组,返回这三个数的和。样例:例如 S = [-1, 2, 1, -4] and target = 1. 和最接近 1 的三元组是 -1 + 2 + 1 = 2.和之前“三数之和”的套路是一致的(详见:点击打开链接)。简单来说,就是先控制一个位置固定,然后对其余两个位置“左右夹逼”,再将这个固定原创 2016-09-06 14:39:26 · 2471 阅读 · 0 评论 -
lintcode - 平面列表
题目描述:给定一个列表,该列表中的每个要素要么是个列表,要么是整数。将其变成一个只包含整数的简单列表。样例:给定 [1,2,[1,2]],返回 [1,2,1,2]。给定 [4,[3,[2,[1]]]],返回 [4,3,2,1]。用递归的思路很容易解决,之前我已经说过太多类似的问题,不再赘述。需要注意的一点是递归“触底”的条件是当这个给出的列表本身是整数。直接给出代码:class原创 2016-09-05 16:45:53 · 1898 阅读 · 0 评论 -
lintcode - 克隆二叉树
题目描述:深度复制一个二叉树。给定一个二叉树,返回一个他的克隆品 。题目把意思已经说得很清楚了,所以不再举例了。非常简单,用一个简单的递归就可以解决,这个思路有点类似于二叉树的前序遍历的递归算法(详见:二叉树的遍历)因为太简单,所以直接给出代码:"""Definition of TreeNode:class TreeNode: def __init__(原创 2016-09-05 08:46:31 · 2391 阅读 · 0 评论 -
lintcode - 用递归打印数字
题目描述:用递归的方法找到从1到最大的N位整数。样例:给出 N = 1, 返回[1,2,3,4,5,6,7,8,9].给出 N = 2, 返回[1,2,3,4,5,6,7,8,9,10,11,...,99].题目要求用递归的方法。那就先来看一下,当N = i 和 N = i + 1时,返回的这个结果列表时怎样转化的。找到“升级”的方式,是递归算法最难的一环。原创 2016-09-01 10:33:29 · 1257 阅读 · 0 评论 -
lintcode - 旋转图像
题目描述:给定一个N×N的二维矩阵表示图像,90度顺时针旋转图像。样例:给出一个矩形[[1,2],[3,4]],90度顺时针旋转后,返回[[3,1],[4,2]]具体怎么转化,大家都知道,现在看看能不能有什么技巧能够使得代码写起来更容易,同时能够支持原地翻转。实际上,对于这种翻转90度的情况,可以这样处理:先按副对角线翻转元素,再按水平中线翻转矩阵的行。如下图所示:原创 2016-08-29 15:00:13 · 884 阅读 · 1 评论 -
lintcode - 图中两个点之间的路线
题目描述:给出一张有向图,设计一个算法判断两个点 s 与 t 之间是否存在路线。样例:如下图,for s = B and t = E, return truefor s = D and t = C, return false题中的数据结构时有向图,关于有向图的定义其实看下面的代码就很容易明白了:class DirectedGraphNode: d原创 2016-08-29 09:50:22 · 1280 阅读 · 0 评论 -
lintcode - 丑数 II
题目描述:设计一个算法,找出只含素因子2,3,5 的第 n 大的数。符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...我们可以认为1也是一个丑数样例:如果n = 9, 返回 10之前,做过一道类似的题目:丑数。题目的要求是判别一个整数是不是丑数。而本题的目的是计算第n个丑数是多少。所以,一种朴素的思路是这样:设定一个计数器,初始为0. 然后从原创 2016-08-28 19:38:05 · 2891 阅读 · 1 评论 -
lintcode - 丑数
题目描述:写一个程序来检测一个整数是不是丑数。丑数的定义是,只包含质因子 2, 3, 5 的正整数。比如 6, 8 就是丑数,但是 14 不是丑数以为他包含了质因子 7。可以认为 1 是一个特殊的丑数。样例:给出 num = 8,返回 true。给出 num = 14,返回 false。显然,这是一个新颖的概念,在传统的数学概念里,找不到“丑数”这个概念,但是这原创 2016-08-28 19:10:46 · 1740 阅读 · 0 评论 -
lintcode - 矩阵归零
题目描述:矩阵归零。给定一个m×n矩阵,如果一个元素是0,则将其所在行和列全部元素变成0。需要在原矩阵上完成操作。样例:给出一个矩阵[ [1, 2], [0, 3]]返回[ [0, 2], [0, 0]]难点在与我们需要对矩阵中为0的元素的位置做一个记录,然后在根据这个记录将相应的位置全部变为0. 而如果先不做记录,而原创 2016-08-28 08:55:51 · 1493 阅读 · 2 评论 -
lintcode - 落单的数 III
题目描述:给出2*n + 2个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字。样例:给出 [1,2,2,3,4,4,5,3],返回 1和5挑战 :O(n)时间复杂度,O(1)的额外空间复杂度我们之前已经做过两道类似的题目,分别是落单的数,落单的数 II,思路都是位运算。这道题也不例外。不过这道题想出方法来倒还真不太容易,至少我当时没想出来,也是后来原创 2016-08-17 15:53:45 · 1446 阅读 · 0 评论 -
落单的数 II
题目描述:给出3*n + 1 个的数字,除其中一个数字之外其他每个数字均出现三次,找到这个数字。样例:给出 [1,1,2,3,3,3,2,2,4,1] ,返回 4题目的挑战还是在于一次遍历,常数级的额外空间复杂度。之前当有2 * n + 1 个数的时候的做法我们已经探讨过了(详见:点击打开链接),用的是位运算的异或,这里,还是用相同的思路。只不过对处理三个相同元素的情况,好像没有类原创 2016-08-14 09:31:31 · 958 阅读 · 0 评论 -
落单的数
题目描述:给出2*n + 1 个的数字,除其中一个数字之外其他每个数字均出现两次,找到这个数字。样例:给出 [1,2,2,1,3,4,3],返回 4这道题本身当然不难。难的是通过一次遍历,常数级的额外空间复杂度,解决问题。所以,第一次碰到这个题目时,确实比较费劲。因为他的解法是比价特殊的,也是非常经典的。那就是位运算。思路可以这样设计,既然位运算中“异或”的操作能消原创 2016-08-13 17:12:40 · 1176 阅读 · 0 评论 -
二叉查找树中搜索区间
题目描述:给定两个值 k1 和 k2(k1 样例:如果有 k1 = 10 和 k2 = 22, 你的程序应该返回 [12, 20, 22].递归+深搜的思路。之前,像类似于“二叉树的所有路径”(详见:点击打开链接)这样的问题用的也是这种思路。应该不会陌生了。用一个结果列表result存储节点值,因为result中需要不断添加新元素,所以,为了方便,干脆再建立一个辅助函数原创 2016-08-13 10:40:32 · 3090 阅读 · 1 评论 -
字符串查找
题目描述:对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1。样例:如果 source = "source" 和 target = "target",返回 -1。如果 source = "abcdabcdefg" 和 target = "bcd",返回 1。原创 2016-08-12 18:39:29 · 1712 阅读 · 0 评论 -
线段树的修改
题目描述:对于一棵 最大线段树, 每个节点包含一个额外的 max 属性,用于存储该节点所代表区间的最大值。设计一个 modify 的方法,接受三个参数 root、 index 和 value。该方法将 root 为跟的线段树中 [start, end] = [index, index] 的节点修改为了新的 value ,并确保在修改后,线段树的每个节点的 max 属性仍然具有正确的值。原创 2016-07-31 11:58:29 · 572 阅读 · 0 评论 -
线段树查询 II
题目描述:对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素) 实现一个 query 的方法,该方法接受三个参数 root, start 和 end, 分别代表线段树的根节点和需要查询的区间,找到数组中在区间[start, end]内的元素个数。样例:对于数组 [0原创 2016-07-31 09:37:49 · 753 阅读 · 0 评论 -
线段树的查询
题目描述:对于一个有n个数的整数数组,在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性max,值为该节点所代表的数组区间start到end内的最大值。为SegmentTree设计一个 query 的方法,接受3个参数root, start和end,线段树root所代表的数组中子区间[start, end]内的最大值。样例:对于数组 [1, 4, 2,原创 2016-07-30 19:59:18 · 1349 阅读 · 0 评论 -
线段树的构造 II
题目描述:线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间。start和end都是整数,并按照如下的方式赋值:根节点的 start 和 end 由 build 方法所给出。对于节点 A 的左儿子,有 start=A.left, end=(A.left + A.right) / 2。对于节点 A 的右儿子,有 start=(A.left +原创 2016-07-30 10:51:49 · 635 阅读 · 0 评论 -
线段树的构造
题目描述:线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间。start和end都是整数,并按照如下的方式赋值:根节点的 start 和 end 由 build 方法所给出。对于节点 A 的左儿子,有 start=A.left, end=(A.left + A.right) / 2。对于节点 A 的右儿子,有 start=(A.left +原创 2016-07-29 16:44:12 · 756 阅读 · 0 评论 -
移动零
题目描述:给一个数组 nums 写一个函数将 0 移动到数组的最后面,非零元素保持原数组的顺序样例:给出 nums = [0, 1, 0, 3, 12], 调用函数之后, nums = [1, 3, 12, 0, 0].其实,仅就实现这个功能来说,我们当然可以选择先把所有的0统计出来,然后删除这些0,再在数组后面添加这些0.不过,这并不是这道题的本意,此题的本意是要我们熟悉数组原创 2016-07-21 10:09:47 · 2209 阅读 · 0 评论 -
合并区间
题目描述:给出若干闭合区间,合并所有重叠的部分。样例:给出的区间列表 => 合并后的区间列表:[ [ [1, 3], [1, 6], [2, 6], => [8, 10], [8, 10], [15, 18] [15, 18]原创 2016-07-18 15:52:47 · 1173 阅读 · 0 评论 -
数字组合 II
题目描述:给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T。C中每个数字在每个组合中只能使用一次。样例:给出一个例子,候选数字集合为[10,1,6,7,2,1,5] 和目标数字 8 , 解集为:[[1,7],[1,2,5],[2,6],[1,1,6]]跟上一题“数字组合”(详见:点击打开链接)其实是一样的,只不过此时不允许列表中的数字被重复利用了。那原创 2016-07-18 13:45:25 · 1103 阅读 · 0 评论 -
数字组合
题目描述:给出一组候选数字(C)和目标数字(T),找到C中所有的组合,使找出的数字和为T。C中的数字可以无限制重复被选取。例如,给出候选数组[2,3,6,7]和目标数字7,所求的解为:[7],[2,2,3]样例:给出候选数组[2,3,6,7]和目标数字7,返回 [[7],[2,2,3]]跟问题“组合”(详见:点击打开链接)从本质上讲是一样的,都是“深搜” + “递归”的方法。只不过原创 2016-07-15 15:59:48 · 1400 阅读 · 0 评论 -
电话号码的字母组合
题目描述:给一个数字字符串,每个数字代表一个字母,请返回其所有可能的字母组合。下图的手机按键图,就表示了每个数字可以代表的字母。与上一题“组合”(详见:点击打开链接)的思路是一致的,用的还是深搜 + 递归这样的模式。首先,可以先构造一个数字与字母相对应的数组,比如,可以写成这个形式:num_alp_table = [" ", "", "abc", "def", "ghi原创 2016-07-11 21:15:54 · 5049 阅读 · 3 评论 -
组合
题目描述:给出两个整数n和k,返回从1......n中选出的k个数的组合。样例:例如 n = 4 且 k = 2,返回的解为:[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4]]深搜+递归的思路。与之前求取“二叉树的所有路径”如出一辙(详见:点击打开链接)。可以这样理解:拿样例来说:1. 先将1放入组合:[1] 那么剩下的数只能在2, 3, 4中选择,因为原创 2016-07-10 21:32:51 · 1737 阅读 · 0 评论 -
上一个排列
题目描述:给定一个整数数组来表示排列,找出其上一个排列。样例:给出排列[1,3,2,3],其上一个排列是[1,2,3,3];给出排列[1,2,3,4],其上一个排列是[4,3,2,1]方法与之前的“下一个排列”问题类似(详见:点击打开链接),如果上一个问题没有搞明白,请先移步给出的链接。在讲解这个问题之前,我会假设你已经完全明白“字典序”,“高位”,“低位”这些概念。好原创 2016-07-10 11:41:22 · 1331 阅读 · 0 评论 -
带重复元素的排列
题目描述:给出一个具有重复数字的列表,找出列表所有不同的排列。样例:给出列表 [1,2,2],不同的排列有:[ [1,2,2], [2,1,2], [2,2,1]]与不带重复元素求取全排列的思路是一样的(详见:点击打开链接),当时我们先讲了递归的思路,简单来说是这样的:1. 先抽取一个元素出来,对剩下的元素做全排列2. 将抽取出的元素依次插入剩原创 2016-07-03 13:03:20 · 3646 阅读 · 0 评论 -
第k个排列
题目描述:给定 n 和 k,求123..n组成的排列中的第 k 个排列。样例:对于 n = 3, 所有的排列如下:123132213231312321如果 k = 4, 第4个排列为,231.关于字典序和排列的概念请翻阅我之前的博文(详见:点击打开链接),由这些概念可知,如果一个排列是第k个排列,那么一定满足他之前的k - 1个排列是按字典序排列好的原创 2016-07-03 10:42:56 · 1595 阅读 · 0 评论 -
全排列
题目描述:给定一个数字列表,返回其所有可能的排列。样例:给出一个列表[1,2,3],其全排列为:[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]排列的规则应该是这样的,假设由n个数字组成,那么,我们先拿出第一个数,设为a,然后让其他的数字做全排列,排列出来的结果中,在每个结果的第一原创 2016-07-01 20:57:50 · 2077 阅读 · 0 评论 -
排列序号
题目描述:给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。样例:例如,排列 [1,2,4] 是第 1 个排列。关于“字典序”和排列的相关基础概念请翻看我之前的博客(详见:点击打开链接),在这篇博客里面我还写了是如何求取一个排列的下一个排列的,如果这些内容你不清楚的话,请先打开链接回看,然后再来做这道题,因为很多内容我会当做你已经很原创 2016-06-30 15:26:36 · 1450 阅读 · 0 评论