算法面试题系列
文章平均质量分 68
sequenceGO
dev
展开
-
【算法题汇总(每天进步一点点)——持续更新中】
2015.07.191. hulu面试题1【100个人,每人头上戴一顶帽子,写有0~99的一个数,数可能重复,每个人都只能看到除自己以外其他人的帽子。每个人需要说出自己的帽子的数,一个人说对就算赢。】分析:一、每个人猜数都是相互独立的,不会互相影响题中只要有一个人对即算赢,那么考虑其对立事件【所有人都没对】,即:100个人,每个人都没猜对自己帽子对应的数,这样每个人说的原创 2015-07-19 23:54:38 · 733 阅读 · 0 评论 -
顺时针打印矩阵(C++版)
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。如:输入矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16依次打印出数字 1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.思路:对于这类题,可使用"转圈"的方法从外向内遍历矩阵。对于遍历到的每一圈,按照从左往右 从上往下 从右往左原创 2015-11-30 21:04:53 · 2944 阅读 · 0 评论 -
二叉树镜像(C++版)
题目:给定源二叉树,设计算法实现其镜像。思路:对于二叉树问题,需要思考除递归方法外的非递归实现。本题递归很好实现,对于遍历到的头结点,每次交换其左右子树即可。之后对其子树递归调用即可。对于非递归实现,需要使用一个辅助栈,用于保存头结点。(层序遍历)注:二叉树结点定义如下:typedef int dataType;struct原创 2015-11-30 21:28:33 · 2255 阅读 · 0 评论 -
从上往下打印二叉树BFS(C++)
题目:从上往下打印出二叉树的每个节点,同层节点从左至右打印。思路:很明显,这是一个BFS遍历问题。使用一个辅助队列即可。和很多二叉树问题一样,使用递归和非递归的方式实现。【注:递归方式将二叉树所有元素压入队列 非递归方式队列中只有一层的结点】贴代码:#include #include #include using namespace std;typ原创 2015-12-01 14:53:10 · 1362 阅读 · 0 评论 -
数组中出现次数超过一半的数字(C++)
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。如果不存在则输出0。如 数组{1,2,3,2,2,2,5,4,2}。数字2在数组中出现了5次,超过数组长度的一半,最终输出2。思路:目前只找到O(n)的解法。初始认为数组第一个数就是目标数(target)。之后遍历数组后面的元素,如果等于目标数,计数++; 否则计数--;如果发现目标数的计数原创 2015-12-01 15:37:30 · 2349 阅读 · 0 评论 -
判断给定序列是否是对应入栈序列的出栈序列(C++)
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。(假设压入栈的所有数字均不相等)如 序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2不可能是该压栈序列的弹出序列。思路:使用一个辅助栈,依次将压栈序列的元素入栈,同时判断出栈序列的元素与栈顶元素是否相等。全部压栈原创 2015-12-01 13:45:40 · 2436 阅读 · 0 评论 -
翻转单词顺序列(C++)
题目:给定一个输入字符串,其中各个单词之间由空格分开,每个单词的字符是顺序的,但是单词之间的顺序是逆序的。实现一个翻转单词序列的算法。如: 输入:student. a am I 输出:I am a student.思路:从左往右遍历字符串,逐个拼接每个单词即可。 贴代码:#include #inc原创 2015-12-02 20:30:00 · 4039 阅读 · 0 评论 -
一行代码求解1-n的累加和(&实现)
题目:求1+2+3+...+n,不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。思路:这类题目一般都需要用到逻辑位运算实现。给出的解法是基于递归实现的,复杂度O(n)。贴代码:int Sum_Solution(int n) { // 递归实现 n && (n += S原创 2015-12-02 20:51:17 · 4075 阅读 · 2 评论 -
数组中只出现一次的数(1)(C++)
题目:一个整型数组里除了1个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。思路:强调数字出现的次数,而且是偶数次。这时候可以考虑利用位运算的 "异或" 实现。2个相同的数异或=0 因此,将数组所有元素异或得到的结果即为只出现一次的那个数。贴代码:#include #include using namespace std;/原创 2015-12-01 16:49:32 · 1103 阅读 · 0 评论 -
数组中只出现一次的数(2)(C++)
题目:一个整型数组里除了2个数字之外,其他的数字都出现了两次。请写程序找出这2个只出现一次的数字。思路:和前一篇文章类似。利用位运算的 "异或" 实现。2个相同的数异或=0 但是这样遍历完数组所有元素之后,得到的是两个只出现一次的数异或的结果。要想分别得到这两个数,还需要进一步思考。按照上一篇文章的思路,我们需要分别将这两个数放在2个不同的子数组,每个数都按原创 2015-12-01 18:07:18 · 372 阅读 · 0 评论 -
整数中X出现的次数(C++)
题目:对于给定的n,求出1-n范围内X出现的次数。(0 思路:这道题nlogn的算法很容易想到。遍历1-n的每个数,判断每个数的每一位是否为1,计数即可。下面直接给出代码:#include using namespace std;int NumberOf1Between1AndN(int n, int x){ int cnt = 0; for(int原创 2015-12-02 20:21:55 · 2036 阅读 · 0 评论 -
不用加减乘除做加法(C++)
题目:设计算法实现两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。思路:位运算 循环实现。代码如下:#include using namespace std;int Add(int num1, int num2){ int andRes; while(num2 != 0) { andRes = num1 & num2原创 2015-12-02 21:05:33 · 1298 阅读 · 0 评论 -
删除排序链表中重复的结点(C++)
题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,最后返回链表头指针。如:链表1->2->3->3->4->4->5 输出为 1->2->5思路:原创 2015-12-03 15:59:21 · 898 阅读 · 0 评论 -
判断数组中是否有重复的数字(C++)
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。思路:这个题目解法很多,这里给出一种解法,充分利用了题目的已知信息。【每个数的范围是 0 - n-1 可能存在多个重复的数字】贴代码:bool duplicate(int numb原创 2015-12-02 21:55:18 · 9337 阅读 · 0 评论 -
二叉树的序列化和反序列化实现(C++)
题目:实现二叉树的序列化和反序列化的函数。思路: 二叉树的序列化 即给定二叉树的头指针,按照某种遍历方式将所有结点链接为一个数组或字符串(/指针)。 反序列化即根据给定的序列重新恢复一颗二叉树。 A. 这里给出的序列化按照二叉树的先序遍历方式将所有结点链接为字符串。 遇到空结点追加'#'原创 2015-12-05 14:39:49 · 3734 阅读 · 1 评论 -
复杂链表的复制(C++)
题目: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点(可以为NULL) )。要求实现一个算法返回一个链表,结构与输入的链表一致(完全的一份拷贝)。注: 链表结点结构如下: struct RandomListNode { i原创 2015-12-04 21:15:46 · 3447 阅读 · 0 评论 -
求字符串的最长无重复字符子串(C++)
题目: 给定一个字符串str,返回str的最长无重复字符子串的长度。 如:"abcd" 返回4 "abcb" 返回3 要求:若字符串的长度为N 算法的时间复杂度为O(N)。思路: 下面给出的算法 时间复杂度为O(N) 空间复杂度为O(M) 其中 :原创 2015-12-06 22:20:37 · 6936 阅读 · 1 评论 -
旋转字符串的判断——KMP实现 (C++)
题目: 给定2个字符串srt1和str2,实现一个算法判断其是否互为旋转字符串。 注: 比如字符串"ABCDE" 那么"BCDEA" "CDEAB" "DEABC" "EABCD"都是其旋转字符串。思路: 这里我们判断str2是否是str1的旋转字符串。原创 2015-12-06 19:37:15 · 675 阅读 · 0 评论 -
合并两个排序的链表(C++版)
题目:已知两个单调递增的链表,要求实现算法合并两个链表,使得成后的链表满足单调不减规则。思路:本题很显然用递归方式很好实现,同时需要注意下算法的鲁棒性【对于空链表的判断】。当然本题还有非递归的版本实现,思想与递归大致一致。每次比较链表1和链表2结点的值,选择较小的结点作为下一个链接的结点。贴代码:注:链表结点的定义如下:struct ListNode {原创 2015-11-29 12:08:24 · 1425 阅读 · 0 评论 -
链表反转(C++版)
题目:实现一个链表反转的算法,注意算法的鲁棒性。注:链表结点的定义如下:struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}}; 直接上代码:ListNode* ReverseList(ListNode* pHead) {原创 2015-11-29 11:13:42 · 976 阅读 · 0 评论 -
实现包含min函数的栈(C++版)
题目:实现一个特殊的栈,要求除了实现基本栈功能,还需要实现返回栈中最小元素的功能。要求:pop() push() top() min()等操作的时间复杂度均为O(1)。思路:考虑使用2个栈,一个用于保存待压入的数据,另一个栈专门用于保存最小值。初始:2个栈都为空 将元素都压入进去。之后:如果待压入的元素 否则 只需要将元素压进数据栈。贴代原创 2015-11-29 11:36:24 · 935 阅读 · 0 评论 -
51nod 数塔取数问题 —— 动态规划
1002 数塔取数问题基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值。每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上。 5 8 4 3 6 97 2原创 2015-12-09 20:26:55 · 2181 阅读 · 0 评论 -
堆排序的递归和非递归实现(C++版)
由一道算法面试题所引发的思考:题目:给定一个数组a, 设计算法判断该数组中是否存在重复的元素。要求:空间复杂度O(1) 时间复杂度尽量低;这道题的答案是采用非递归的堆排序算法实现。(时间复杂度O(n) 空间复杂度O(1)) 注:如果是递归实现的堆排序 空间复杂度为O(logn)下面直接贴代码。堆排序递归:// 交换元素 void swap(int *p1, int *p2)原创 2015-11-23 14:39:18 · 4620 阅读 · 3 评论 -
链表的分化问题(C++)
题目:对于一个链表,需要用一个特定阈值完成对它的分化,使得小于等于这个值的结点移到前面,大于该值的结点在后面, 同时保证两类结点内部的位置关系不变。 给定一个链表的头结点head,同时给定阈值val,请返回一个链表,使小于等于它的结点在前,大于等于它的在后,保证结点值不重复。如:输入:{1, 4, 2, 5}, 3输出:{1, 2, 4, 5}思路原创 2015-12-09 21:58:56 · 437 阅读 · 0 评论 -
有序矩阵查找的快速算法(C++版)
题目:行和列都排好序的矩阵,请设计一个高效算法,快速查找矩阵中是否含有值x。给定一个int矩阵mat,同时给定矩阵大小nxm及待查找的数x,请返回一个bool值,代表矩阵中是否存在x。所有矩阵中数字及x均为int范围内整数。保证n和m均小于等于1000。思路:判断矩阵右上角元素与待查找元素的大小,利用矩阵行列都有序的特性, 每次取出一行或一列元素。算法时间复杂度原创 2015-11-23 22:08:25 · 2389 阅读 · 0 评论 -
合并两个有序数组(C++版)
题目:两个从小到大排序以后的数组A和B,其中A的末端有足够的缓冲空容纳B。请编写一个方法,将B合并入A并排序。给定两个有序int数组A和B,A中的缓冲空用0填充,同时给定A和B的真实大小int n和int m,请返回合并后的数组。思路:从后向前逐个比较填充A数组。贴代码:int cmpMax(int a, int b) {原创 2015-11-23 21:15:51 · 3517 阅读 · 0 评论 -
三色排序问题/(荷兰国旗问题)(C++版)
题目:有一个只由0,1,2三种元素构成的整数数组,请使用交换、原地排序而不是使用计数进行排序。给定一个只含0,1,2的整数数组A及它的大小,请返回排序后的数组。算法复杂度:时间 O(N)空间 O(1)贴代码:void swap(int *p1, int *p2) { int temp = *p1; *p1 = *p2; *p2 = te原创 2015-11-23 21:51:49 · 4329 阅读 · 0 评论 -
待排序的最短子数组长度(C++版)
题目:思路:分别从左->右:记录最大元素值 比较最大元素值和当前遍历元素的大小 如果 最大值 > 当前元素 记录当前元素下标, 直至数组遍历完成。 —— index1和右->左:记录最小元素值 比较最小元素值和当前遍历元素的大小 如果 最小值 最后返回 (index1 - index2 + 1)注释:如果原数组是有序的 那么返回0即可。贴代原创 2015-11-23 22:41:36 · 555 阅读 · 0 评论 -
求数组相邻元素差值的最大值快速算法(C++版)
题目:整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数的最大差值。给定一个int数组A和A的大小n,请返回最大的差值。保证数组元素多于1个。思路:基于桶排序思想 n个数 n+1个桶 最后一个桶存最大数 那么最大差值一定在非空桶的相邻2个桶之间 且=(空桶右边 min -空桶左边max)算法复杂度:时间复杂度:O(n)空原创 2015-11-23 23:49:03 · 6647 阅读 · 1 评论 -
变形词(C++版)
题目:对于两个字符串A和B,如果A和B中出现的字符种类相同且每种字符出现的次数相同,则A和B互为变形词,请设计一个高效算法,检查两给定串是否互为变形词。给定两个字符串A和B及他们的长度,请返回一个bool值,代表他们是否互为变形词。思路:统计各字符串中字符出现的次数 逐次比较即可。注:C++中字符串的ASCII码范围0~255 因此可以用固定长度数组代替HashMap节省存储空间。原创 2015-11-24 00:46:38 · 1303 阅读 · 0 评论 -
判断一个数是否回文数的巧妙解法
·回文数的定义:对于非负数 其左右两边完全相同 则是回文。 e.g: 121 11 等对于负数 其绝对值左右两边完全相同 则是回文。 e.g: -121 -11 等设计一个算法判断给定的数是否为回文数,如果是,输出true 反之 输出false;贴代码:#include #include using namespace std;bool isPad原创 2015-11-25 00:01:37 · 7301 阅读 · 0 评论 -
获取窗口最大值数组 O(n)解法
题目:一个整型数组num 窗口大小w 从左到右滑动窗口。窗口滑动过程中每次都会产生一个最大值。【总共产生n - w + 1个窗口】思路:常规解法:O(n*w)的解法复杂度太高。本题解法复杂度:O(n) 大致思想如下:维护一个双端队列dq 记录遍历的元素下标。 记:num[i]为当前遍历到的元素 dq队尾元素为j。若 num[i] 若 num[i] >= nu原创 2015-11-25 00:42:08 · 482 阅读 · 0 评论 -
利用两个队列实现一个栈(C++版)
题目:利用两个队列实现一个栈的功能,完成pop() push() top() empty()等功能。push(x) -- Push element x into stack.pop() -- Removes the element on top of the stack.top() -- Get the top element.empty() -- Return whether t原创 2015-11-26 00:50:35 · 2121 阅读 · 0 评论 -
利用两个栈实现一个队列(C++版)
题目:利用两个栈实现一个队列的功能,完成pop() push() peek() empty()等功能。push(x) -- Push element x to the back of queue.pop() -- Removes the element from in front of queue.peek() -- Get the front element.empt原创 2015-11-25 23:45:50 · 781 阅读 · 0 评论 -
判断是否存在拓扑结构相同的子树(C++版)
题目:对于两棵彼此独立的二叉树A和B,请编写一个高效算法,检查A中是否存在一棵子树与B树的拓扑结构完全相同。给定两棵二叉树的头结点A和B,请返回一个bool值,代表A中是否存在一棵同构于B的子树。实现思路:将两颗树按照相同的遍历方式序列化为字符串 之后问题就转化为字符串匹配问题 大大降低时间复杂度【O(n+m)】。注:1. 常规的解决思路是树的遍历 逐个节点比较 这样的时间原创 2015-11-24 23:15:14 · 920 阅读 · 0 评论 -
二叉树遍历之递归实现(C++版)
题目:实现递归的二叉树遍历(前序遍历 中序遍历 后序遍历)。 思路:常规的二叉树遍历方式采用栈实现,比较容易实现,下面直接给出代码。注:二叉树结点定义如下:typedef int dataType;struct Node{dataType val;struct Node *left;struct Node *right;Node(dataType _原创 2015-11-27 09:29:25 · 917 阅读 · 2 评论 -
二叉树神级遍历算法——Morris遍历(C++版)
题目:设计一个算法实现二叉树的三种遍历(前序遍历 中序遍历 后序遍历)。要求时间复杂度为O(n) 空间复杂度为O(1)。 思路:空间复杂度O(1)的要求很严格。常规的递归实现是显然不能满足要求的[其空间复杂度是树的深度O(h) ]。本篇文章介绍著名的Morris遍历,该方法利用了二叉树结点中大量指向null的指针。常规的栈结构遍历方式,遍历到某个节点之后并不能回到上层的结点原创 2015-11-27 14:36:57 · 10881 阅读 · 2 评论 -
布隆过滤器初识
题目:不安全网页黑名单包含100亿个黑名单网页,每个网页的URL最多占用64B。现在要实现一种网页过滤系统,可以根据网页的URL判断该网页是否在黑名单上。要求:该系统允许有0.01%的误判率。使用的额外空间不超过30GB。思路:首先对所有的URL通过哈希保存进而查询显然是不可能的,不满足第二个要求。(空间需求达到了640GB)对于 网页黑名单系统 & 垃圾邮件过原创 2015-11-28 23:44:44 · 370 阅读 · 0 评论 -
链表指定值清除(C++)
题目: 有一个单链表。链表中每个节点保存一个整数,给定一个值val,把所有等于val的节点删掉。 给定一个单链表的头结点head,同时给定一个值val,返回清除后的链表的头结点,保证链表中有不等于该值的其它值。 同时保证其他元素的相对顺序。 如:原创 2015-12-09 22:41:26 · 1398 阅读 · 0 评论