算法学习
文章平均质量分 62
tommyzht
这个作者很懒,什么都没留下…
展开
-
先序非递归遍历二叉树解析——面试高频数据结构
一、基本概念二叉树是笔试面试中高频数据结构。而二叉树的遍历是解决一切二叉树题目的基础。因此,有必要熟练掌握二叉树的遍历方法,包括递归方法 和 非递归方法。由于递归方法比较简单,因此,这里我们着重来学习二叉树的非递归遍历方法。首先明确,二叉树的遍历方法按照访问根节点的次序不同,可以分为如下三种:先序遍历、中序遍历、后序遍历。先序遍历,即先访问根节点,然后再分别访问原创 2015-07-17 22:45:39 · 1191 阅读 · 0 评论 -
面试题03_二维数组中查找_剑指offer系列
题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。解题思路:这是一道考查二维数组的理解和编程能力的题。在二维数组在内存中是连续存储的。在内存中从上到下存储各行元素,在同一行中按照从左到右存储。因此可以按照行号和列号来计算出相对数组首部的位置。原创 2015-07-17 14:44:43 · 619 阅读 · 0 评论 -
面试题29_数组中出现次数超过一半的数字
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。解题思路出现超过一半的数,一定是排好序的数组的中位数,即位置为 n/2 的数。找到这个中位数,然后,遍历一次,判断是否出现次数超过一半,若是,则返回true,否则,没有这原创 2015-07-29 09:21:53 · 1067 阅读 · 0 评论 -
LintCode_138——子数组和为零
题目:给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置。样例给出[-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3].解题思路:依次求数组的前缀和,同时执行如下操作:假定当前位置是i,查找i之前位置的前缀和,是否存在j位置,使得,j位置的前缀和 等于 i位置的前缀和。若有,则j 到原创 2015-08-10 17:30:28 · 3235 阅读 · 0 评论 -
面试题04_替换空格_剑指Offer系列
题目描述请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。解题思路这种题目从前往后扫描的话,需要移动多次,这种情况下从后往前扫描。首先扫描一遍,找到空格的个数,算出需要添加多少个20%,即替换后的字符串的长度 = 原字符串长度 + 空格数*2准备两个指针一个原创 2015-07-17 15:05:28 · 630 阅读 · 0 评论 -
面试题31——连续子数组的最大和
题目描述输入一个数组,有正数也有负数,求连续子数组的最大和。解题思路典型动态规划设f(i) 表示 以i位置结尾的子数组和,那么有:递推式:f(i) = max{ f(i-1) + array[i], array[i] }初值:f(0) = array[0]实现代码class Solution {public: int Find原创 2015-07-29 14:30:18 · 697 阅读 · 0 评论 -
面试题30——最小的k个数
题目描述输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。解题思路思路1:按递增排序,然后输出前k个数,简单粗暴,时间复杂度O(nlogn)思路2:利用partition算法,找到第K大数,输出其左边K个数,时间复杂度O(n)思路3:开一个规模为K的数组,遍历原数组,若辅助数组未存满K个数,那么直接将遍历原创 2015-07-29 13:57:26 · 706 阅读 · 0 评论 -
面试题25_二叉树中和为某一值的路径
题目描述输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。解题思路当用先序遍历的方式访问某一结点时候,我们把该结点加入到当前路径,并计算累加和。若累加和刚好等于输入的整数,并且该节点为叶子节点,那么当前路径符合要求。如果当前节点不是叶子节点,那么继续访问它的子节点。当前原创 2015-07-28 13:53:04 · 934 阅读 · 0 评论 -
面试题27_二叉搜索树与双向链表
题目描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。解题思路采用中序遍历方法,注意指针指向。left指向小于当前值的数,right指向大于当前值的数。利用pLast来指向当前转换好的链表的最大值,即最后一个节点。首先转换左子树,其次,连接上根节点,之后,转换右子树。实现原创 2015-07-28 21:13:28 · 582 阅读 · 0 评论 -
面试题_28——字符串的全排列
题目描述输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 解题思路这个题目就是求字符串的全排列,C++ STL有一个函数next_permutation() 可以求的字典序下一个排列。因此,利用该STL函数可以很方便就求出答案。如果要自己实现原创 2015-07-28 21:35:37 · 567 阅读 · 0 评论 -
面试题26_带随机指针的链表复制
题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。解题思路思路一:分两步:第一步,遍历一遍链表,挨个复制;O(n)第二步,遍历链表,挨个找随机指针,因为定位随机指针要从头开始,所以每一个节点的随机指针都要从头开始找;时间复杂度是:O(n^2)思路二:分三步:第一步:挨个复制,链接在原原创 2015-07-28 20:31:27 · 944 阅读 · 0 评论 -
面试题23_从上往下打印二叉树
题目描述:从上往下打印出二叉树的每个节点,同层节点从左至右打印。解题思路:这道题考查二叉树的层次遍历。对于二叉树的先序遍历、中序遍历、后续遍历,我们都比较熟悉,用递归方法实现,代码也非常简单。对于层次遍历,我们在实现的时候,需要借助一个队列来辅助。依次将层次遍历的到的节点压入队列,再从队列中依次取出来打印。实现代码:/*struct TreeNod原创 2015-07-27 20:19:22 · 626 阅读 · 0 评论 -
面试题33_把数组排成最小的数
题目描述输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。解题思路这道题是一个排序问题,但是要自定义排序规则。需要注意的问题是:拼接起来的数可能超出整型数的表示范围,因此这也是一个大数问题。用字符串来表示解决溢出问题。实现代码c原创 2015-07-30 23:04:04 · 716 阅读 · 0 评论 -
面试题35_第一个只出现一次的字符
题目描述在一个字符串(1解题思路思路一:暴力解法,双重循环,依次判断每个字符出现的次数,直到找到第一个只出现一次的字符。时间复杂度O(n^2)。思路二:利用hash表来存储每个元素出现的次数,时间O(n) ,空间O(1)实现代码class Solution {public: int FirstNotRepeatingChar原创 2015-07-31 09:41:39 · 512 阅读 · 0 评论 -
面试题34_丑数
题目描述把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。解题思路思路一:从一开始,逐个判断是不是丑数,一直到找到第N个丑数。这种方法会做很多无用计算。把不是丑数的数也统统计算了一遍,会超时。思路二:可不可以只计算丑数?答案是原创 2015-07-31 09:36:19 · 639 阅读 · 0 评论 -
常见排序算法总结
1、常见的数据结构排序算法总结如下:#include"iostream"using namespace std;/*一、直接插入排序基本思想:前i-1个数是有序的,将第i个数插入到合适的位置。1、设置标记temp = arr[i];2、对i进行插入排序,从j=i-1个数开始向前查找,若arr[j] > temp ,则 arr[j+1] = arr[j];直到循环原创 2015-10-05 17:20:19 · 801 阅读 · 0 评论 -
面试题_64——数据流中的中位数
题目描述:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。解题思路:数据流证明是输入数据大小是动态变化的。我们要从动态变化的数据流中找现有数据的中位数。首先需要考虑,这些数据流中的数据该怎么存储?即 用什么数据结构进行存储? 从而原创 2015-09-03 17:18:23 · 911 阅读 · 0 评论 -
面试题54——表示数值的字符串
题目描述请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。解题思路:这道题没什么别的技巧,按照数值的表示规则,逐个扫描字符串,看是否符合要求。数值有如下几种情况:1、原创 2015-08-19 09:56:54 · 911 阅读 · 0 评论 -
面试题40_数组中只出现一次的数字
题目描述一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。解题思路:若是数组中只有一个数字出现一次,其余的数字都出现偶数次,那么直接将数组中所有的数进行异或运算,得到的最后的结果就是出现一次的数(出现奇数次的数字)但是,题目要求是有两个数出现一次,那么上述方法得到的结果是这两个数的一个异或结果。我们可以考虑:原创 2015-08-04 10:58:35 · 741 阅读 · 0 评论 -
面试题41_和为连续序列
输出描述:输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序。解题思路:设置small 和 big 前后两个指针,累加small->big之间和,是否为给定和。若是,则输出;若小于,则big后移,big++; cursum += big;若大于,则small后移,cursum -= small;small++;原创 2015-08-04 11:29:39 · 617 阅读 · 0 评论 -
面试题38_数字在排序数组中出现的次数
题目描述统计一个数字在排序数组中出现的次数。解题思路数组是排序的,所以重复出现的数字是相邻排列的。用二分查找算法,找到第一次出现的位置,和 最后一次出现的位置。判断第一次出现的位置条件为:当前数字的前一个是否与之相等,若是则继续查找,否则该位置就是第一次出现的位置。判断最后一次出现的位置条件为:当前数字的后一个是否与之相等,若是则继续查找,否则该位置就是最后一次出现的位置。原创 2015-08-03 00:08:51 · 1010 阅读 · 0 评论 -
面试题37_两个链表的第一个公共结点
题目描述输入两个链表,找出它们的第一个公共结点。解题思路1、首先遍历两个链表,获得各自长度,得到长度差k2、让长的链表先走K 步3、两个链表同时向后走,同时判断是否相等,若相等则返回。时间复杂度:O(n),空间复杂度O(1)实现代码/*struct ListNode { int val; struct ListNode *next; L原创 2015-07-31 23:21:24 · 591 阅读 · 0 评论 -
面试题06_重建二叉树——剑指offer系列
题目描述输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},输出它的头节点。解题思路:在二叉树先序序列中,第一个节点就是根节点。在中序序列中找到该根节点,那么以该根节点为轴将中序序列分为左右两个部分。左边原创 2015-07-20 23:11:35 · 647 阅读 · 0 评论 -
字符串反转之——手摇算法
手摇算法(也叫三次反转算法)看题:将字符串abcdefg,变成efgabcd,要求空间复杂度O(1)。解答:第一步:将子串abcd反转,变成dcba。源字符串变成dcbaefg第二步:将字串efg反转,变成gfe。源字符串变成dcbagfe第三步:将整个字符串dcbagfe反转,变成efgabcd。手摇算法常常被用来旋转字符串。同时,手摇算法也可以用来做原地归并原创 2015-07-31 10:05:50 · 1106 阅读 · 0 评论 -
找中位数O(n)算法
题目描述:给定一个未排序的整数数组,找到其中位数。中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序后数组的第N/2个数。样例给出数组[4, 5, 1, 2, 3], 返回 3给出数组[7, 9, 4, 5],返回 5解题思路:利用快排划分的思想,递归处理。参考代码:public class Solution {p原创 2015-07-21 10:09:29 · 16796 阅读 · 3 评论 -
面试题_53——正则表达式匹配
题目描述请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配解题思路从左到右,逐个匹配判断:1、若*(pattern原创 2015-08-13 09:27:35 · 1677 阅读 · 0 评论 -
面试题36_数组中的逆序对
题目描述在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 解题思路思路一:暴力搜索,一次判断每一个数,其之后的数有没有比它小的,若有则计数加一。时间O(n^2) 思路二:利用归并排序方法,在归并的时候,计算逆序对数目。具体过程看代码。 时间O(nlogn)实现代码原创 2015-07-31 10:48:24 · 661 阅读 · 0 评论 -
面试题22_栈的压入和弹出序列
题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。解题思路:这道题考查对数据结构中栈的理解只有充分理解了栈的特性,才能够写出准确无误的代码。两个原创 2015-07-27 19:57:07 · 630 阅读 · 0 评论 -
面试题24_二叉搜索树的后序遍历序列
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。解题思路首先明确基本概念,什么是二叉搜索树?二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小原创 2015-07-27 21:07:06 · 769 阅读 · 0 评论 -
面试题08_旋转数组的最小数字——剑指offer系列
题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如:数组{3, 4, 5, 1 , 2} 是 数组{1,2,3,4,5}的一个旋转,该数组最小的数是1.我们要做的就是找到这个旋转后数组的最小数。解题思路:思路1:直接遍历数组,找到最小的数,简单粗暴,时间复杂度O(n),空间复杂度O(原创 2015-07-25 10:28:32 · 1056 阅读 · 0 评论 -
动态规划算法总结
1、基本概念动态规划是一种求解多阶段决策(优化)问题的算法设计技术,其主要思想是:将原问题规约为规模较小、结构相同的子问题,建立原问题与子问题优化函数间的依赖关系。从规模最小的子问题开始,利用上述依赖关系求解规模更大的子问题,直到得到原始问题的解为止。动态规划算法的适用条件适用于求解多阶段决策(优化)问题,该问题的解可以表示为一个决策序列,且满足优化原则(或最有子结构性原创 2015-06-03 20:37:45 · 1343 阅读 · 0 评论 -
翻转链表——链表
题目描述:给定一个链表,要求将这个链表进行翻转。时间O(n),空间O(1)解题思路:设定三个指针,temp, prev,head,从头到尾依次翻转。head代表当前节点,prev代表前一个节点,temp代表下一个节点。参考代码:/** * Definition of ListNode * * class ListNode { * public:原创 2015-06-23 09:13:17 · 1044 阅读 · 0 评论 -
n!阶乘末尾有多少个零0
题目: 初阶:1*2*3*……*100 求结果末尾有多少个零。 进阶: N的阶乘末尾有多少个0分析: 一般类似的题目都会蕴含某种规律或简便方法的阶乘末尾一个零表示一个进位,则相当于乘以10而10 是由2*5所得,在1~100当中,可以产生10的有:0 2 4 5 6 8 结尾的数字,显然2是确定的,因为4、6、8当中都含有因子2,所以都可看当是2,那么关键在于5的数量了那么该问题的实质是要求出转载 2015-06-01 13:46:42 · 17726 阅读 · 1 评论 -
Two Strings Are Anagrams-LintCode
题目描述:写出一个函数 anagram(s, t) 去判断两个字符串是否是颠倒字母顺序构成的 样例 给出 s=”abcd”,t=”dcab”,返回 true思路1: 分别对字符串s 和 t 进行排序,然后,再比较是否相等,若相等则返回true,否则,返回false。 时间复杂度:排序O(nlogn)+比较O(n)=O(nlogn) 注意:初始条件,判断是否为空串class Solution原创 2015-05-22 18:13:34 · 1909 阅读 · 0 评论 -
TopK问题详解
1. 基本topK问题描述:从1百万个数中找出最大(或最小)的5个数看到这个问题,很多同学的第一反应会是:排序。那么,选择哪种排序方法呢,有同学说:快排,将所有数排序后,再选出最大的5个。虽然快排确实能解决这个问题,但是需要对1百万个数排序,但我们仅仅需要其中的5个。那么,有更好的方法吗?还记得我们之前介绍的选择类排序算法吗?我们说过,选择类排序算法,最大的特点就是能在一轮排序后获得最终排转载 2015-05-18 15:10:18 · 3426 阅读 · 0 评论 -
二叉树的最小深度——广度优先搜索
题目描述;给定一个二叉树,找出其最小深度。二叉树的最小深度为根节点到最近叶子节点的距离。解题思路:这个题目比较简单。对于二叉树的问题,首先想到的是采用递归,广度优先搜索。一个节点一个节点地遍历,直到第一次找到叶子节点为止。注意编程的细节,代码里面有注释参考代码:(C++)/** * Definition of TreeNod原创 2015-06-18 10:25:52 · 1189 阅读 · 0 评论 -
第k大的数——分治法
问题描述:初阶:有两个数组A和B,假设A和B已经有序(从大到小),求A和B数组中所有数的第K大。进阶:有N台机器,每台机器上有一个有序的大数组,需要求得所有机器上所有数中的第K大。注意,需要考虑N台机器的并行计算能力。思路:初阶:比较A[k/2]和B[k/2],如果A[k/2]>=B[k/2]那么A的前k/2个数一定都在前k-1大中,将A数组前k/2个数扔掉,反之扔原创 2015-05-30 10:26:24 · 2488 阅读 · 0 评论 -
选择类排序-堆排序 简单选择排序
选择类排序,每一趟在n - i + 1 ( i = 1,2, … , n - 1)个记录中选取关键字最小的记录作为有序序列中的第i个记录。 区别于插入类排序和交换类排序,选择类排序在排序过程完成前,就能通过一趟排序,获得最终有序序列中处于特定位置的元素。这使得选择类排序在TopK问题中,得到广泛的应用。TopK问题:从无序的n个元素中,选出最大或最小的K(在笔试\面试的过程中,topK问题往往要利转载 2015-05-18 15:25:08 · 713 阅读 · 0 评论 -
排序算法总结之——归并排序
定义归并就是将两个或多个有序的序列合并成一个有序序列的过程。二路归并排序是面试中考查最多的排序算法之一。归并排序有两种: 1、一般归并排序,空间复杂度O(n) 2、原地归并排序,空间复杂度O(1)一般归并排序基本思想:将两个或者两个以上的有序表合成一个新的有序表。 归并排序无论是顺序存储还是链式存储结构都有较好的性能。时间复杂度:O(nlogn) 空间复杂度:O(n) 是否稳定:是举例说明原创 2015-05-30 11:56:25 · 758 阅读 · 0 评论 -
分治策略总结
1、基本概念分治策略是一种算法设计技术,其主要思想是:将原问题划分(或者归约)为彼此独立的、规模较小而结构相同的子问题,递归地求解所有的子问题并将子问题的解组合从而得到原问题的解。2、分治算法的设计步骤a、分解:将原问题划分或者归约为若干个子问题,子问题必须与原问题具有相同的结构,每个子问题可独立求解。对于输入划分时注意保持子问题规模的均衡。b、递归求解:按次序递归求解每个原创 2015-05-30 11:06:18 · 1004 阅读 · 0 评论