自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

guoziqing506的博客

记录学习点滴,享受算法乐趣

  • 博客(41)
  • 收藏
  • 关注

原创 链表倒数第n个节点

题目描述:找到单链表倒数第n个节点,保证链表中节点的最少数量为n。样例:给出链表 3->2->1->5->null和n = 2,返回倒数第二个节点的值1.因为链表是不能回溯的,同时也不像数组那样,每个元素都存有一个自然的索引,可以实现快速查找,所以,我们在这里,通过两个指针来解决这个问题。想一想之前在“排序链表转换为二分查找树”中,我们求取链表中间节点值的方法,是通过快慢指针,快指针为

2016-04-30 19:33:04 1198

原创 合并两个排序链表

题目描述:将两个排序链表合并为一个新的排序链表样例:给出 1->3->8->11->15->null,2->null, 返回 1->2->3->8->11->15->null。之前学过合并两个排序数组(详见:点击打开链接),基本的思路是用两个指针分别指向两个数组中的元素,按照所指元素的大小关系,依次排列。具体的原理如果不明白,请回看我刚才给的链接。那么合并两个链表呢?从本质上讲没什么不同,

2016-04-29 15:12:04 928

原创 在O(1)时间复杂度删除链表节点

题目描述:给定一个单链表中的表头和一个等待被删除的节点(非表头或表尾)。请在在O(1)时间复杂度删除该链表节点。并在删除该节点后,返回表头。样例:给定 1->2->3->4,和节点 3,返回 1->2->4。还是在删链表的节点。正常的删除前面已经提过(详见:点击打开链接),现在增加了难度,要求在O(1)的时间复杂度内删除。时间复杂度的要求使得我们不能通过遍历的方法找到相关节点,而由上一

2016-04-28 21:01:42 1958

原创 删除链表中的元素

题目描述:删除链表中等于给定值val的所有节点。样例:给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5。最基本的删除操作,主要学习的是“摘链”的过程。由链表的结构特性可知(详见:点击打开链接),单链表(简称链表,若无特别说明,链表都是单链表)是不能回溯的,就是说找不到这个节点的前一个节点,而所谓删除一个元素实际上

2016-04-28 14:17:58 5265 2

原创 链表简述

其实学习编程的时候,一开始差不多都是先写出“hello, world”,其后就开始接触数组了,因为使用计算机完成计算的一个重大优势就是可以进行批量处理(想一想用手算或者使用普通计算器是做不到这一点的),而将要处理的数据存储在一个数组里面就实现了这种功能。数组是最基本的数据结构,他是顺序存储数据的,也就是说,每个数据在数组当中都有一个隐含的索引(基本上都是从0开始的所谓数组的下标),下标加上数据本身

2016-04-28 13:55:22 1100

原创 最小差

题目描述:给定两个整数数组(第一个是数组 A,第二个是数组 B),在数组 A 中取 A[i],数组 B 中取 B[j],A[i] 和 B[j]两者的差越小越好(|A[i] - B[j]|)。返回最小差。样例:给定数组 A = [3,4,6,7], B = [2,3,8,9],返回 0。还记得之前做过一道“合并排序数组”的问题(详见:点击打开链接)。当时是选用了两个指针,分别指向两个数组,然

2016-04-27 09:36:59 1521

原创 字符大小写排序

题目描述:给定一个只包含字母的字符串,按照先小写字母后大写字母的顺序进行排序。样例:给出"abAcD",一个可能的答案为"acbAD"跟排颜色的题(详见:点击打开链接)是一样的。(额。。。我也不知道为什么同样的问题,他会出这么多),所以我不讲了。就是通过交换,将小写全部放到数组前面。代码在下面:class Solution: """ @param chars: The

2016-04-27 09:04:49 1790

原创 第k大元素

题目描述:在数组中找到第k大的元素样例:给出数组 [9,3,2,4,8],第三大的元素是 4;给出数组 [1,2,3,4,5],第一大的元素是 5,第二大的元素是 4,第三大的元素是 3,以此类推和上一道中位数的题(详见:点击打开链接)是一模一样的,需要注意的是,数组既然要按升序排列,那么第k大元素就是数组的倒数第k位,也就是索引为n - k的元素,还是按照快排的思想,通过一个分割函数找到

2016-04-27 08:18:22 1072

原创 中位数

题目描述:给定一个未排序的整数数组,找到其中位数。中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序后数组的第N/2个数。样例:给出数组[4, 5, 1, 2, 3], 返回 3;给出数组[7, 9, 4, 5],返回 5目的是要找到排在最中间的那个数。这不由使人回想起快速排序,快排每次都是令枢轴排在它该排在的位置。而其他位置的元素未必是排好序的。那么我们可以这样来思考

2016-04-26 22:32:39 1928

原创 链表插入排序

题目描述:用插入排序对链表排序样例:Given 1->3->2->0->null, return 0->1->2->3->null之前,在我的博文“将排序链表转换为二分查找树”(详见:点击打开链接)中已经介绍了链表的快慢指针法,以及“摘链”和“链接”的基本操作,现在,我们以这道题为例,继续熟悉链表的基本操作。插入排序的原理我就不多解释了(详见:点击打开链接),简单说就是往一个已经排

2016-04-26 22:11:16 1374

原创 数组划分

题目描述:给出一个整数数组nums和一个整数k。划分数组(即移动数组nums中的元素),使得:1. 所有小于k的元素移到左边2. 所有大于等于k的元素移到右边返回数组划分的位置,即数组中第一个位置i,满足nums[i]大于等于k。样例:给出数组nums=[3,2,2,1]和 k=2,返回 1很简单的快排分割的应用。我们的思路跟前面讲过的“颜色分类”(详见:点击打

2016-04-24 17:21:08 1817

原创 排颜色 II

题目描述:给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,...k的顺序进行排序。样例:给出colors=[3, 2, 2, 1, 4],k=4, 你的代码应该在原地操作使得数组变成[1, 2, 2, 3, 4]与上一道颜色排列的问题(详见:点击打开链接)不同之处在于现在有多个元素,所以直接进行快速排序即可,是有重

2016-04-23 21:47:38 951 1

原创 颜色分类

题目描述:给定一个包含红,白,蓝且长度为 n 的数组,将数组元素进行分类使相同颜色的元素相邻,并按照红、白、蓝的顺序进行排序。我们可以使用整数 0,1 和 2 分别代表红,白,蓝。样例:给你数组 [1, 0, 1, 2], 需要将该数组原地排序为 [0, 1, 1, 2]。想一想这个问题,其实就是对三个不同数字组成的数组排序。因为就三个不同数字,所以自然而然想到桶排序(详见:点击打

2016-04-23 20:01:22 1380

原创 Left Pad

这道题我主要把他的意思说清楚一点:就是说一个字符串,我现在给定一个长度(默认这个长度一定是大于或等于字符串长度的),如果字符串长度比这个给定的长度小了,就在字符串前面添加一些符号,使得生成的新字符串长度都相等。样例:‘abc’,我现在给定长度5,填充的符号为‘ ’(空字符),显然,'abc'的长度比5小,那就在‘abc’前面添加两个空字符,变成‘  abc’就行了。需要注意的是,这里的pad这

2016-04-22 17:01:06 1059

原创 Wiggle Sort

题目描述:给出一个无序的数组,在原地将数组排列成符合以下规律:nums[0] = nums[2] 样例:Given nums = [3, 5, 2, 1, 6, 4], one possible answer is [1, 6, 2, 5, 3, 4].题目Wiggle Sort中的Wiggle是“扭动,摇摆”的意思。你看这个规律就能发现,排好序的数组应该是一个波浪式的前进。那

2016-04-22 16:17:34 767

原创 排序列表转换为二分查找树

题目描述:给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树我们之前做过一道将排序数组转换为二分查找树的问题,详见:点击打开链接将链表转换为二分查找树与上面这道题的基本思想一模一样(在这里,高度平衡,也就是高度最小),所以我们要解决的问题就是查找到排序链表的中值,作为根节点,然后将链表分割,分别按照同样的思想生成左右子树。(如果对这个算法有疑问,请先搞懂我刚才给出的链接

2016-04-21 19:51:51 2005 2

原创 子树

题目描述:有两个不同大小的二进制树: T1 有上百万的节点; T2 有好几百的节点。请设计一种算法,判定 T2 是否为 T1的子树。子树的判断,当然很容易想到递归。因为可以这样来考虑:如果树A是树B的子树,那么有三种可能性:1. 只要B是空,那B一定是A的子树2. 当B不空时,A若空,那么一定不是3. 当A和B都不空时,要么A和B完全一样(我在这里说的是同样位置的节点所包含的值一样

2016-04-20 17:04:57 736

原创 生成括号

题目描述:给定 n 对括号,请写一个函数以将其生成新的括号组合,并返回所有组合结果。样例:给定 n = 3, 可生成的组合如下: "((()))", "(()())", "(())()", "()(())", "()()()"这道题就有些难度了。想一想这种生成括号的规则,其实隐含了一条信息:那就是始终左括号的数量要大于或等于右括号的数量。为了方便理解,我现在假设n = 2,那么根据

2016-04-20 10:10:49 1327

原创 平衡二叉树

题目描述:给定一个二叉树,确定它是高度平衡的。对于这个问题,一棵高度平衡的二叉树的定义是:一棵二叉树中每个节点的两个子树的深度相差不会超过1。 牢牢把握平衡二叉树的定义,任何节点的左右子树高度差的绝对值不能超过一,换个说法,任何节点的两个子树高度差不超过一,且两个子树都是平衡的。可以看出,问题这样升级:左右子树高度差绝对值不超过一,且左右子树都平衡,则这棵树平衡;触底的条件:空树平衡好

2016-04-19 22:22:16 814

原创 二叉树的最大深度

从现在起,我将用几节的内容讲解递归的相关题目,因为递归的方法是非常重要的,也是面试常问到的问题。前面,我们已经对递归的基本思想和用法做过归纳,详见:点击打开链接,也解决过相关问题。这里再总结一下,递归就是要在问题中找两个东西:1. 问题由小问题到大问题是如何“升级”的2. 递归何时“触底”那么现在来看这样一个问题:求二叉树的最大深度思路非常简单,一棵二叉树,它的最大深度就是左右

2016-04-19 22:07:16 874

原创 把排序数组转换为高度最小的二叉搜索树

题目描述:给一个排序数组(从小到大),将其转换为一棵高度最小的二叉搜索树。样例:给出数组 [1,2,3,4,5,6,7], 返回首先,先来看一下二叉搜索树(也称为二叉排序树)的定义:它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉

2016-04-18 22:49:04 3089

原创 二叉树的所有路径

题目描述:给一棵二叉树,找出从根节点到叶子节点的所有路径。样例:递归 + 深搜的思路。还记得之前学过的用递归的方法解决二叉树的前序遍历的问题吗?点击打开链接,用的就是深搜的策略,递归实现。我们在这里,依然用这种逻辑基本解法可以这样描述:从根节点出发找叶子,找到叶子之后,所有这条“找寻之路”上的所有节点构成了我们要打印出来的一条路径。所以,我们需要建立一个全局变量pa

2016-04-18 13:29:32 5851

原创 二叉树的锯齿形层次遍历

题目描述:给出一棵二叉树,返回其节点值的锯齿形层次遍历(先从左往右,下一层再从右往左,层与层之间交替进行)样例:如果之前的二叉树的层次遍历(详见我的博文:点击打开链接)你已经完全搞懂的话,这道题其实基本对你是没有什么意义的,他还是层次遍历,只不过相邻每两层之间输出的顺序相反。那这个是很容易解决的,设置一个bool型的变量,每次判断是该从左往右,还是从右往在即可。然后每遍历一层,

2016-04-17 10:42:08 4314

原创 二叉树的层次遍历

题目描述:给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问)样例:之前,我们已经学习了用非递归的解法解决二叉树的前序遍历,中序遍历,后序遍历。对于这三种深搜的策略,我采用了一种特殊的结构——栈。其实,我在之前也谈过,一般深搜可以用栈解决,而广搜,是可以用队列解决的,二叉树的层次遍历,就是一种典型的广度优先搜索。当然,关于广度优先搜索其实问题远不止层次遍历这么简单,这个以后会

2016-04-16 23:20:24 4188

原创 二叉树的后序遍历

这是二叉树的三种主要遍历方式的最后一种了,前面两种我们已经讨论过,后序遍历其实就是将策略转换成了"左-右-根",其他方面跟前两种一样,都是深搜的逻辑。前两种详见以下链接:前序遍历:点击打开链接中序遍历:点击打开链接好,回到已经用了三次的那张老图:后序遍历的结果应该是:DEBFGCA这也是三种遍历模型中最难的一个。因为要先访问左右两个孩子,再访问其父节点。如果按照以前的方

2016-04-15 12:49:14 886 4

原创 二叉树的中序遍历

之前讲了非递归的二叉树的前序遍历,我们用的是栈的方法,本节看看如何通过栈实现二叉树的中序遍历。还是先看这幅图,因为中序遍历的策略是“左-根-右”,所以,就这幅图而言,结果应该是DBEAFCG在之前做前序遍历的时候,我建立了一个栈,通过先加入根节点,再删除后加入右节点,左节点的逻辑关系,合理的控制了数据运行的流程,详见:点击打开链接在中序遍历这里,比前序遍历要难一点,难在什么地方

2016-04-15 09:40:36 1217 1

原创 二叉树的前序遍历

题目描述:给出一棵二叉树,返回其节点值的前序遍历。要求不能用递归。什么是前序遍历应该已经很清楚了,样例我就省略了。关于二叉树的前序遍历,我之前已经详细讲过,当时是用的最简单的递归解决这个问题的,详见:点击打开链接,但是递归是有它的天然缺陷的,那就是效率低。所以,有人试图用一种更高效的办法替代递归。就这个问题来说,由于二叉树的前序遍历用的是“深搜”的策略(中序遍历,后序遍历也都是“深

2016-04-14 20:17:11 1373

原创 深度优先搜索

深度优先搜索(Depth First Search)是一种遍历图中节点的策略,顾名思义,其核心思想是:只要可能,就在图中尽可能“深入”。具体来说,我们从图中一个节点出发(可以设这个节点为V1),按照某种策略寻找到V1的一条出发边,延出发边找到下一个节点(设为V2),再按照刚才的策略,找到v2的一条出发边,再去找新的节点。。。以此类推,直到不能再“深入”了(方便起见,我现在假设搜索到了节点Vn,上一

2016-04-14 13:34:03 1364

原创 搜索旋转排序数组 II

题目描述:跟进“搜索旋转排序数组”,假如有重复元素又将如何?是否会影响运行时间复杂度?如何影响?为何会影响?写出一个函数判断给定的目标值是否出现在数组中。样例:给出[3,4,4,5,7,0,1,2]和target=4,返回 true这是上一道搜索旋转排序数组的升级版,详见:点击打开链接,只不过考虑了有重复元素的情况。还记得我们之前做过一道求旋转排序数组中最小值的问题吧,先回顾一下,

2016-04-14 09:35:32 1398

原创 搜索旋转排序数组

题目描述:假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。你可以假设数组中不存在重复的元素。样例:给出[4, 5, 1, 2, 3]和target=1,返回 2给出[4, 5, 1, 2, 3]和target=0,返回 -1回忆

2016-04-13 08:32:59 4141

原创 搜索区间

题目描述:给定一个包含 n 个整数的排序数组,找出给定目标值 target 的起始和结束位置。如果目标值不在数组中,则返回[-1, -1]样例:给出[5, 7, 7, 8, 8, 10]和目标值target=8,返回[3, 4]还记得在学习二分查找时遇到的第一个问题吗?要求返回目标值第一次在数组中出现的位置,详见:点击打开链接。那么现在问题就可以简化了:我们可以先通过二分法找到

2016-04-12 22:03:18 929

原创 x的n次幂

题目描述:实现一个函数,计算x的n次方样例:Pow(2.1, 3) = 9.261Pow(0, 1) = 0Pow(1, 0) = 1题目的意思很简单,就是实现一个简单的pow函数。既然出现在二分法的章节里,我们当然想到用二分法解决之。一个数的n次方可以看做是它的(n / 2)次方的平方,然后他的(n / 2)次方又是(n / 4)次方的平方。。。。以此类推,每个求幂运算都“二分”后平方。显然,不难发现这是一个二分法和递归思想(有关递归的基本思想详见:点击打开链接)的综合运用。

2016-04-11 22:11:44 1883

原创 最长上升子序列

题目描述:给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度。说明一下,最长上升子序列的定义:最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的。样例:给出[5,4,1,2,3],这个LIS是[1,2,3],返回 3给出[4,2,4,5,3,7],这个LIS是[4,4,5,7],返回 4对一

2016-04-10 17:50:02 622

原创 第一个错误的代码版本

题目描述:代码库的版本号是从 1 到 n 的整数。某一天,有人提交了错误版本的代码,因此造成自身及之后版本的代码在单元测试中均出错。请找出第一个错误的版本号。你可以通过 isBadVersion 的接口来判断版本号 version 是否在单元测试中出错,具体接口详情和调用方法请见代码的注释部分。样例:给出 n=5调用isBadVersion(3),得到fal

2016-04-10 09:14:20 1270

原创 寻找峰值

题目描述:你给出一个整数数组(size为n),其具有以下特点:相邻位置的数字是不同的,A[0] A[n - 1],假定P是峰值的位置则满足A[P] > A[P-1]且A[P] > A[P+1],返回数组中任意一个峰值的位置。样例:给出数组[1, 2, 1, 3, 4, 5, 7, 6]返回1, 即数值 2 所在位置, 或者6, 即数值 7 所在位置。最简单的想法可以通过遍

2016-04-07 15:37:55 1942

原创 寻找旋转排序数组中的最小值 II

题目描述:假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2)。你需要找到其中最小的元素。数组中可能存在重复的元素。样例:给出[4,4,5,6,7,0,1,2]  返回 0好了,跟上一道题“寻找旋转排序数组中的最小值”(详见:点击打开链接)相比,其实求取的东西本质上没有发生变化,我们还是按照上次讲的逻辑(具体看链接)将数组

2016-04-06 11:42:23 865

原创 寻找旋转排序数组中的最小值

题目描述:假设一个旋转排序的数组其起始位置是未知的(比如:0 1 2 4 5 6 7 可能变成是:4 5 6 7 0 1 2)。你需要找到其中最小的元素。你可以假设数组中不存在重复的元素。样例:给出[4,5,6,7,0,1,2]  返回 0从本质上讲,跟排序数组中查找target是一个道理。但是有两点不同:(1)是一个经过旋转的排序数组。(2)找的是最小的元素首先,我们

2016-04-04 21:08:52 1804

原创 二叉树的遍历

所谓二叉树的遍历,就是把二叉树的所有树节点依次输出,每个节点只输出一次,且所有节点都被输出。我们常见的遍历方式一共是四种:前序遍历,中序遍历,后序遍历,以及层次遍历。概念上,前三种一般被称为深度优先遍历(与深度优先搜索的逻辑是一致的,关于深度优先搜索详见:),而层次遍历一般被称为广度优先遍历。在lintcode上,就这四种方法,就分别有一道题目与之对应。当然,题目永远是次要,通过题目理解二叉树的构

2016-04-04 19:36:45 1320 3

原创 递归(斐波那契数列)

递归是一种极为常用的编程思想。比较官方的解释是“可以在函数内部,直接或间接地调用函数自身”,我一般把他称为“一种有技术含量的偷懒算法”。为什么这么说呢?因为递归函数不需要我们对运算过程的每一步的细节了解详细,而只需要我们知道两点:1. 函数是如何“升级”的。也就是这一步需要解决的问题与其子问题之间的关系2. 函数到什么位置“触底”,“触底”后返回什么?

2016-04-04 19:26:47 1392

原创 x的平方根

题目描述:实现 int sqrt(int x) 函数,计算并返回 x 的平方根。样例:sqrt(3) = 1sqrt(4) = 2sqrt(5) = 2sqrt(10) = 3解法:还是典型的二分法的使用,实际上求取的是平方不大于x的最大整数。那么可以用left,right两个指针分别指向两个整数,逼近要求取的值。于是,按照二分法的“标配”(点击打开

2016-04-03 09:27:53 1321

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除