本篇文章给大家谈谈深入解析面试必备:算法与数据结构核心问题,以及对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。
输入一棵二叉搜索树,并将二叉搜索树转换为有序双向链表。
要求不创建新节点,只调整指针指向。
10
/
6 14
//
4 8 12 16
转换为双向链表
4=6=8=10=12=14=16。
首先我们定义的二叉搜索树节点的数据结构如下:
结构体BSTreeNode
{
int m_n值; //节点的值
BSTreeNode *m_pLeft; //节点的左子节点
BSTreeNode *m_pRight; //节点的右子节点
};
2. 设计一个包含min函数的堆栈。
定义栈的数据结构需要添加一个min函数来获取栈的最小元素。
函数min、push和pop的时间复杂度要求为O(1)。
3. 求子数组的最大和
话题:
输入一个整数数组,数组中有正数和负数。
数组中的一个或多个连续整数组成一个子数组,每个子数组都有一个和。
求所有子数组的最大和。所需的时间复杂度为O(n)。
例如输入数组为1, -2, 3, 10, -4, 7, 2, -5,最大子数组为3, 10, -4, 7, 2,
所以输出是子数组18 的总和。
4、查找二叉树中所有和为某个值的路径
问题:输入一个整数和一个二叉树。
从树的根节点开始,一直到叶子节点,所经过的所有节点就形成了一条路径。
打印出总和等于输入整数的所有路径。
例如输入整数22,得到如下二叉树
10
/
5 12
/
4 7
然后打印出两条路径:10,12和10,5,7。
二叉树节点的数据结构定义为:
struct BinaryTreeNode //二叉树中的节点
{
int m_n值; //节点的值
二叉树节点*m_pLeft; //节点的左子节点
二叉树节点*m_pRight; //节点的右子节点
};
5.求最小的k个元素(用小根堆和大根堆来解决)
问题:输入n个整数,输出k个最小的。
例如,如果输入8 个数字:1、2、3、4、5、6、7 和8,则最小的4 个数字是1、2、3 和4。
公共静态无效FindKMin(int []排序,int k)
{
int[] 堆=排序;
int rootIndex=k/2 - 1;
而(根索引=0)
{
重新堆(堆, rootIndex, k - 1);
根索引--;
}
for (int i=k, len=heap.Length; i len; i++)
{
如果(堆[i]}
私有静态无效重新堆(int []堆,int rootIndex,int lastIndex)
{
int 孤儿=堆[rootIndex];
布尔完成=假;
int leftIndex=rootIndex * 2 + 1;
while (!done leftIndex=lastIndex)
{
int LargeIndex=左索引;
if (leftIndex+1=lastIndex)
{
int 右索引=左索引+ 1;
if (堆[右索引] 堆[左索引])
{
较大索引=右索引;
}
}
if (孤儿堆[largerIndex])
{
堆[rootIndex]=堆[largerIndex];
根索引=较大索引;
左索引=根索引* 2 + 1;
}
别的
{
完成=真;
}
}
堆[rootIndex]=孤儿;}
问题6
腾讯面试题:
给你10分钟,给出上排的十个数字,并填写下排对应的十个数字。
要求下排的每个数字是上排的十个数字在下排出现的次数。
上排十个数字如下:
【0,1,2,3,4,5,6,7,8,9】
举个例子,
值: 0,1,2,3,4,5,6,7,8,9
分配: 6,2,1,0,0,0,1,0,0,0
0 在下一行出现6 次,1 在下一行出现2 次,
2 在下一行出现了一次,3 在下一行出现了0 次.
等等.
完整代码如下:
include
使用命名空间std;
常量int Len=4;
bool isLegal(int* A,int n)
{
for(int i=0;i
{
整数计数=0;
for(int j=0;j
{
如果(i==A[j])
++计数;
}
if(A[i] !=计数)
返回假;
}
返回真;
}
void ArrayF(int* A,int n,int Sum)
{
if(!A || n 1 || Sum 1)//异常处理,A==NULL,n=0,Sum1
返回;
如果(n==1)
{
A[0]=总和;
if(isLegal(A,Len))
{
for(int i=0;i
库特
库特
}
}
别的
{
for(int i=0;i=Sum;++i)
{
A[n-1]=i;
ArrayF(A,n-1,Sum-i);
}
}
}
无效主()
{
int A[20]={0};
ArrayF(A,Len,Len);
}
问题7
微软亚洲学院编程确定两个链表是否相交
给定两个单向链表的头指针,例如h1和h2,判断两个链表是否相交。
为了简化问题,我们假设两个链表都没有环。
问题延伸:
1.如果链表可能有圆柱怎么办?
2、如果需要找到两个链表相交的第一个节点列怎么办?
问题8
1.有两个房间,一个房间有三个灯,另一个房间有三个开关,控制三个灯。
两个房间是分开的,一个房间看不到另一个房间。
现在要求学员进入这两个房间一次,然后判断这三个灯控制哪个开关。
可以做什么?
(先打开A灯一段时间,然后关闭A灯并打开B灯,进入一个有灯的房间,得出:上的灯是B灯。在暗的两个灯中,热的光是A光,剩下的是C光)
2.你让一些人为你工作7天,你必须用金条支付他们的工资。金条被分成七小块,每天赠送一块。
如果你只能切割两次金条,你如何将它分配给这些工人呢?
3. 使用算法反转链表的顺序。现在再次执行此操作,无需递归。
a1 -a2 -a3
第一对:(NULL,a1) —— 开始
第二对:(a1,a2)
第三对:(a2,a3)
第四对:(a3,NULL) —— 完成
//非递归翻转
无效Reverse_non_recursive(){
节点*pair1=NULL;
节点*pair2=头;
while (pair2!=NULL){
节点*temp=pair2-下一个;
配对2-下一个=配对1;
对1=对2;
对2=温度;
}
头=对1;
}
使用算法将节点插入到循环链表中,而不需要遍历链表。
使用算法排列数组。你为什么选择这种方法?
使用算法来匹配通用字符串。
反转字符串。针对速度进行了优化。优化空间。
颠倒句子中的单词顺序,例如“我的名字是Chrissy”到“Chrissy 叫我”,
以最少的动作达到最快的速度。
找到一个子串。针对速度进行了优化。优化空间。
比较两个字符串需要O(n) 时间和恒定空间。
假设您有一个包含1001 个整数的数组,任意排列,但您知道所有整数都在1 到1000(含)之间。而且,除了一个数字出现两次外,其他数字都只出现一次。假设你只能处理这个数组一次,并使用算法找到重复的数字。如果在运算中使用辅助存储,你能找到不使用这种方法的算法吗?
无需乘法或加法即可增加8 倍。现在用同样的方法将其增加7倍。
问题9
判断一个整数序列是否是二叉搜索树后序遍历的结果
(思路是序列中的最后一个节点一定是根节点,从前向后遍历,比根节点小的就是它的左子树,位于序列的左半部分,比它大的就是它的左子树)右子树并且应该位于其右侧的一半。)
include
使用命名空间std;
void test(const int data[],int start,int node,bool flag){
如果(标志开始
int 左=开始;
while(data[node]data[left]){ //获取其左子树
左++;
}
for(int j=左;j
如果(数据[j]
}
测试(数据,0,左1,标志); //递归
测试(数据,左,节点1,标志);
}
}
int 主函数(无效){
布尔标志=真;
int a[]={5,7,6,9,11,10,8};
测试(a,0,6,标志);
if(flag) cout"是"
否则cout"不"
int b[]={7,4,6,5};
测试(b,0,3,标志);
if(flag) cout"是"
否则cout"不"
系统("暂停");
返回0;
}
问题10
翻转句子中的单词顺序。
问题:输入一个英文句子,翻转句子中的单词顺序,但单词内的字符顺序保持不变。
句子中的单词之间用空格分隔。为简单起见,标点符号被视为普通字母。
例如,如果您输入“I am a Student.”,则输出将为“student.a am I”。
问题11
求二叉树中节点之间的最大距离.
如果我们将二叉树视为图,则父节点和子节点之间的连接被视为双向的。
让我们将“距离”定义为两个节点之间的边数。
写一个程序,
查找二叉树中两个最远节点之间的距离。
问题12
问题:求1+2+…+n,
要求不能使用乘除、for、while、if、else、switch、case、条件判断语句(A?B:C)等关键字。
问题13:
问题:输入一个单向链表,输出链表中倒数最后一个节点的第k个节点。链表的倒数第二个节点是链表的尾指针。
链表节点定义如下:
结构体列表节点
{
int m_nKey;
ListNode* m_pNext;
};
问题14:
问题:输入一个数组和一个已按升序排列的数字。
在数组中查找两个数字,使其总和恰好等于输入的数字。
所需的时间复杂度为O(n)。如果多对数字之和等于输入数字,则输出任意一对。
例如,输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。
问题15:
问题:输入一棵二叉搜索树,并将该树转换为其镜像。
也就是说,在转换后的二叉搜索树中,左子树的节点大于右子树的节点。
采用递归和循环两种方法完成树图像变换。
例如输入:
8
/
6 10
/ /
5 7 9 11
输出:
8
/
10 6
/ /
11 9 7 5
将二叉搜索树的节点定义为:
struct BSTreeNode //二叉搜索树(BST)中的一个节点
{
int m_n值; //节点的值
BSTreeNode *m_pLeft; //节点的左子节点
BSTreeNode *m_pRight; //节点的右子节点
};
问题16:
标题(微软):
输入一棵二叉树,从上到下逐层打印树的每个节点,同一层从左到右打印。
例如输入
8
/
6 10
//
5 7 9 11
输出8 6 10 5 7 9 11。
问题17:
问题:找出字符串中第一个只出现一次的字符。如果输入abaccdeff,则输出b。
分析:这道题是2006年Google笔试题。
问题18:
问题:n 个数字(0,1,…,n-1) 围成一个圆,从数字0 开始,
每次从该圆中删除第m 个数字(第一个是当前数字本身,第二个是当前数字的下一个数字)。
删除一个号码后,继续删除下一个号码中的第m 个号码。
找到圆圈中剩下的最后一个数字。
July:我想很多人都已经看到这个话题了。
问题19:
问题:定义斐波那契数列如下:
/0 n=0
f(n)=1 n=1
f(n-1)+f(n-2) n=2
输入n 并使用最快的方法查找序列的第n 项。
分析:很多C语言教材在讲递归函数时,都会以斐波那契为例。
因此,很多程序员都非常熟悉用递归解决这个问题,但是……哈哈,你知道的。
问题20:
问题:输入一个代表整数的字符串,将字符串转换为整数并输出。
例如,如果输入字符串“345”,则将输出整数345。
问题21
2010年中兴通讯面试题
编程解决方案:
输入两个整数n和m,从序列1,2,3.n中选取任意数字,
为了使总和等于m,需要列出所有可能的组合。
问题22:
有4张红牌和4张蓝牌。主持人先取任意两张牌,然后将任意两张牌分别放在A、B、C的额头上。
A、B、C都可以看到另外两个人额头上的牌。读完后,要求他们猜猜额头上有什么颜色的卡片。
A说不知道,B说不知道,C说不知道,A说知道。
请告诉我如何推理以及A如何知道。
如果使用程序,如何实现?
问题23:
用最简单、最快的方法来计算下面的圆是否与正方形相交。 "
3D坐标系原点(0.0,0.0,0.0)
: 轮
半径r=3.0
中心o=(. 0.0,)
方形:
4个角坐标;
1:(. 0.0,)
2:(. 0.0,)
3:(. 0.0,)
4:(. 0.0,)
问题24:
链表操作,
(1).单链表原地反转,
(2) 合并链表
问题25:
编写一个函数,其原型为int continumax(char *outputstr,char *intputstr)
功能:
找到字符串中最长的连续数字串,并返回该字符串的长度。
并将这个最长的数字字符串付给函数参数outputstr之一指向的内存。
例如:将"abcd12345ed125ss123456789"的首地址传递给inputstr后,函数将返回9,
outputstr指向的值为123456789
26. 左旋弦
话题:
定义字符串的左旋转操作:将字符串前面的几个字符移动到字符串的末尾。
例如,将字符串abcdef左移2位,得到字符串cdefab。请实现字符串左旋转的功能。
对长度为n的字符串进行操作所需的时间复杂度为O(n),辅助存储器为O(1)。
27. 跳步问题(其实这是斐波那契公式)
问题:楼梯有n 层。如果一次可以跳1 级,那么也可以跳2 级。
找出总共有多少跳,并分析算法的时间复杂度。
/
yuucf 版权所有。 2011.08.16
/
include "stdafx.h"
include
使用命名空间std;
int JumpStep(int n)
{
如果(n=0)返回0;
if (n==1 || n==2) 返回n;
返回(JumpStep(n-1) + JumpStep(n-2));
}
int _tmain(int argc, _TCHAR* argv[])
{
int nStep=0;
cout "请输入步数:";
cin nStep;
cout "步数为"nStep",那么一共有"JumpStep(nStep)"种跳转方法。"结束;
返回0;
}
这个问题最近经常出现,包括在MicroStrategy这样比较注重算法的公司里。
他们都选择了这个问题作为面试题或者笔试题。
28.整数的二进制表示形式中1的个数
问题:输入一个整数,求该整数的二进制表达式中有多少个1。
例如输入10,由于其二进制表示为1010,有两个1,所以输出为2。
汉明权重
intcalculate_one(intn)
{
n=(n0x55555555) + ((n1)0x55555555);
n=(n0x33333333) + ((n2)0x33333333);
n=(n0x0f0f0f0f) + ((n4)0x0f0f0f0f);
n=(n0x00ff00ff) + ((n8)0x00ff00ff);
n=(n0x0000ffff) + ((n16)0x0000ffff);
返回n;
}
方法二
intcalculate_one(intn)
{
整数计数=0;
而(n!=0){
n=n-1;
计数++;
}
返回计数;
}
29. 堆栈压入和弹出序列
问题:输入两个整数序列。其中一个序列代表堆栈的压入顺序,
确定另一个序列是否可能是相应的弹出序列。
为了简单起见,我们假设推送序列中的任何两个整数都不相等。
例如,如果输入的推送序列是1、2、3、4、5,则4、5、3、2、1可能是弹出序列。
因为可以有以下的push和pop序列:
推1、推2、推3、推4、弹出、推5、弹出、弹出、弹出、弹出、
这样得到的出栈序列为4,5,3,2,1。
但序列4, 3, 5, 1, 2 不能是入栈序列1, 2, 3, 4, 5 的出栈序列。
其想法是:将输入的入栈序列与弹出序列的第一位进行比较。如果不同,则将它们压入堆栈。如果它们相同,则跳过它们。同时,pop序列的元素也向后移动一位。
include
include
使用命名空间std;
bool isPopSerial(int push[], int pop[], int n)//我自己写的一个方法,注意函数名
{
int i=0,j=0;
堆栈我的堆栈;
while(i n)//只要不是所有压入数组都压入栈
{
mystack.push(push[i]);
我++;
while(!mystack.empty() mystack.top()==pop[j])
{
mystack.pop();
j++;
}
}
if(mystack.empty() j==n)//最后一个是出栈序列的唯一条件:栈变空,出栈序列光标到达末尾
返回真;
return false;//除此之外,它不是一个pop序列}
30.1到n的正数中1出现的次数
问题:输入一个整数n,求1到n的n个整数的十进制表示中出现1的次数。
include
2 #包括
3 使用命名空间std;
4
5 int NumbersOf1sFrom1ToN(无符号int n)
6 {
7 int 当前N=n;
8
9 //计数器
10 int cnt=0;
11
12 //商,计算该数包含多少个10、100、1000等
13 整数商=0;
14
15 //取余,计算排除“integer”包含后剩余数字中包含1的个数
16 int 余数=0;
17 号
18 //每个循环中的权重记录10、100、1000分别包含多少位1、十位、百位;
19 int 乘法=1;
20
21 while(当前N)
22 {
23商=当前N/10;
24余数=当前N%10;
25
26 //包括多少个10、100、1000,乘以对应的个位数字1、十位数字1、百位数字1
27 cnt +=商* 乘数;
28
29 //如果余数大于1,则本轮再加一个权重
30 如果(余数1)
31{
32 cnt +=乘数;
33}
34 //余数等于1
35 else if(余数==1)
36{
37 cnt +=n - 当前N * mult + 1;
38}
39
40
41 当前N=当前N/10;
42乘*=10;
43}
44
45返回cnt;
46}
47
48 int main()
49{
50 cout"请输入号码N:"
51 无符号整型数=0;
52 cinnumber;
53
54 cout"从1到N中1的个数为:"
55 计算
56 返回0;
}
31、结构类似蜂窝的图,搜索最短路径(需要5分钟)
迪杰斯特拉算法
include
include
include
使用命名空间std;
define INFINITY 65535//无边时的权值
define MAX_VERTEX_NUM 10//最大顶点数
t
ypedef struct MGraph{ string vexs[10];//顶点信息 int arcs[10][10];//邻接矩阵 int vexnum, arcnum;//顶点数和边数 }MGraph; int LocateVex(MGraph G, string u)//返回顶点u在图中的位置 { for(int i=0; i if(G.vexs[i]==u) return i; return -1; } void CreateDN(MGraph &G)//构造有向网 { string v1, v2; int w; int i, j, k; cout<<"请输入顶点数和边数:"; cin>>G.vexnum>>G.arcnum; cout<<"请输入顶点:"; for(i=0; i>G.vexs[i]; for(i=0; i>v1>>v2>>w; i=LocateVex(G, v1); j=LocateVex(G, v2); G.arcs[i][j]=w; }} //迪杰斯特拉算法求有向网G的v0顶点到其余顶点v的最短路径p[v]及带权长度D[v] //p[][]=-1表示没有路径,p[v][i]存的是从v0到v当前求得的最短路径经过的第i+1个顶点(这是打印最短路径的关键),则v0到v的最短路径即为p[v][0]到p[v][j]直到p[v][j]=-1,路径打印完毕。 //final[v]为true当且仅当v∈S,即已经求得从v0到v的最短路径。 void ShortestPath_DIJ(MGraph G, int v0, int p[][MAX_VERTEX_NUM], int D[]) { int v, w, i, j, min; bool final[10]; for(v=0; vv->w的距离<目前v0->w的距离 D[w]=min+G.arcs[v][w];//更新D[w] for(j=0; j} void main() { int i, j; MGraph g; CreateDN(g); int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//最短路径数组p int D[MAX_VERTEX_NUM];//最短距离数组D ShortestPath_DIJ(g, 0, p, D); cout<<"最短路径数组p[i][j]如下:"<-1) cout<} 有两个序列a,b,大小都为n,序列元素的值任意整数,无序; 要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。 例如: var a=[100,99,98,1,2, 3]; var b=[1, 2, 3, 4,5,40];include "stdio.h"
include "stdlib.h"
void balanceArray(int a[],int b[],int n); int sumArray(int a[],int n); int main(void) { int i; int a[5]={0,1,2,3,4},b[5]={5,6,7,8,9}; balanceArray(a,b,5); for(i=0;i<5;i++) printf("%3d",a[i]); printf("n"); for(i=0;i<5;i++) printf("%3d",b[i]); printf("n"); return 0;} void balanceArray(int a[],int b[],int n) { intp,q; int i,j,itemDValue,sumDValue,tmp,flag=1; if(sumArray(a,n)< sumArray(b,n)) { p = b; q = a; } while(flag) { flag=!flag; for(i=0;i0)) { flag=!flag; tmp = p[i]; p[i] = q[j]; q[j] = tmp; } } } }} int sumArray(int a[],int n) { int i,count=0; for(i=0;i count += a[i]; return count; } 实现一个挺高级的字符匹配算法: 给一串很长字符串,要求找到符合要求的字符串,例如目的串:123 1******3***2 ,12*****3这些都要找出来 其实就是类似一些和谐系统。。。。。 实现一个队列。 队列的应用场景为: 一个生产者线程将int类型的数入列,一个消费者线程将int类型的数出列 求一个矩阵中最大的二维矩阵(元素和最大).如: 1 2 0 3 4 2 3 4 5 1 1 1 5 3 0 中最大的是: 4 5 5 3 要求:(1)写出算法;(2)分析时间复杂度;(3)用C写出关键代码 //非最优解include
using namespace std; int max_matrix(int (*array)[5], int maxx, int maxy, int& posi, int& posj) { int max = 0; int i = 0, j = 0; while(i< maxx - 1) { j = 0; while( j< maxy - 1) { int t = array[i][j] + array[i+1][j] + array[i][j+1] + array[i+1][j+1]; if( max< t) { max = t; posi = i; posj = j; } j ++; } i ++; } return max; } int main() { int a[3][5] = {{1,2,0,3,4}, {2,3,4,5,1}, {1,1,5,3,0}}; int i = 0, j = 0; int max = max_matrix(a, 3, 5, i, j); cout<< "max num: "<< max< cout<< "matrix: "<< endl; cout<< a[i][j]<< " "<< a[i][j+1]<< endl; cout<< a[i+1][j]<< " "<< a[i+1][j+1]<< endl; } 第36题-40题(有些题目搜集于CSDN上的网友,已标明): 36.引用自网友:longzuo 谷歌笔试: n支队伍比赛,分别编号为0,1,2。。。。n-1,已知它们之间的实力对比关系, 存储在一个二维数组w[n][n]中,w[i][j] 的值代表编号为i,j的队伍中更强的一支。 所以w[i][j]=i 或者j,现在给出它们的出场顺序,并存储在数组order[n]中, 比如order[n] = {4,3,5,8,1......},那么第一轮比赛就是 4对3, 5对8。....... 胜者晋级,败者淘汰,同一轮淘汰的所有队伍排名不再细分,即可以随便排, 下一轮由上一轮的胜者按照顺序,再依次两两比,比如可能是4对5,直至出现第一名 编程实现,给出二维数组w,一维数组order 和 用于输出比赛名次的数组result[n], 求出result。 有n个长为m+1的字符串, 如果某个字符串的最后m个字符与某个字符串的前m个字符匹配,则两个字符串可以联接, 问这n个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。 百度面试: 1.用天平(只能比较,不能称重)从一堆小球中找出其中唯一一个较轻的,使用x次天平, 最多可以从y个小球中找出较轻的那个,求y与x的关系式。 answer:二分法 2.有一个很大很大的输入流,大到没有存储器可以将其存储下来, 而且只输入一次,如何从这个输入流中随机取得m个记录。 3.大量的URL字符串,如何从中去除重复的,优化时间空间复杂度 网易有道笔试: (1). 求一个二叉树中任意两个节点间的最大距离, 两个节点的距离的定义是 这两个节点间边的个数, 比如某个孩子节点和父节点间的距离是1,和相邻兄弟节点间的距离是2,优化时间空间复杂度。 (2). 求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边, 有向图不再连通,描述算法。 40.百度研发笔试题 引用自:zp155334877 1)设计一个栈结构,满足一下条件:min,push,pop操作的时间复杂度为O(1)。 2)一串首尾相连的珠子(m个),有N种颜色(N<=10), 设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。 并分析时间复杂度与空间复杂度。 3)设计一个系统处理词语搭配问题,比如说 中国 和人民可以搭配, 则中国人民 人民中国都有效。要求: *系统每秒的查询数量可能上千次; *词语的数量级为10W; *每个词至多可以与1W个词搭配 当用户输入中国人民的时候,要求返回与这个搭配词组相关的信息。 41.求固晶机的晶元查找程序 晶元盘由数目不详的大小一样的晶元组成,晶元并不一定全布满晶元盘, 照相机每次这能匹配一个晶元,如匹配过,则拾取该晶元, 若匹配不过,照相机则按测好的晶元间距移到下一个位置。 求遍历晶元盘的算法 求思路。 42.请修改append函数,利用这个函数实现: 两个非降序链表的并集,1->2->3 和 2->3->5 并为 1->2->3->5 另外只能输出结果,不能修改两个链表的数据。 43.递归和非递归俩种方法实现二叉树的前序遍历。 44.腾讯面试题: 1.设计一个魔方(六面)的程序。 2.有一千万条短信,有重复,以文本文件的形式保存,一行一条,有重复。 请用5分钟时间,找出重复出现最多的前10条。 3.收藏了1万条url,现在给你一条url,如何找出相似的url。(面试官不解释何为相似) 45.雅虎: 1.对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右) 某一个元素也加一,现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。 2.一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值 比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1; {3,6}{2,4,3} m=2 {3,3}{2,4}{6} m=3 所以m的最大值为3 46.搜狐: 四对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(()) 47.创新工场: 求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2} 48.微软: 一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5} 是由{6,5,4,3,2,1}左移两位形成的,在这种数组中查找某一个数。 49.一道看上去很吓人的算法面试题: 如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1) 50.网易有道笔试: 1.求一个二叉树中任意两个节点间的最大距离,两个节点的距离的定义是 这两个节点间边的个数, 比如某个孩子节点和父节点间的距离是1,和相邻兄弟节点间的距离是2,优化时间空间复杂度。 2.求一个有向连通图的割点,割点的定义是, 如果除去此节点和与其相关的边,有向图不再连通,描述算法。 51.和为n连续正数序列。 题目:输入一个正数n,输出所有和为n连续正数序列。 例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。 分析:这是网易的一道面试题。 52.二元树的深度。 题目:输入一棵二元树的根结点,求该树的深度。 从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 例如:输入二元树: 10 / 6 14 / / 4 12 16输出该树的深度3。 二元树的结点定义如下: struct SBinaryTreeNode // a node of the binary tree { int m_nValue; // value of node SBinaryTreeNode *m_pLeft; // left child of node SBinaryTreeNode *m_pRight; // right child of node}; 分析:这道题本质上还是考查二元树的遍历。 53.字符串的排列。 题目:输入一个字符串,打印出该字符串中字符的所有排列。 例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串 abc、acb、bac、bca、cab和cba。 分析:这是一道很好的考查对递归理解的编程题, 因此在过去一年中频繁出现在各大公司的面试、笔试题中。 54.调整数组顺序使奇数位于偶数前面。 题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分, 所有偶数位于数组的后半部分。要求时间复杂度为O(n)。 题目:类CMyString的声明如下: class CMyString { public: CMyString(char* pData = NULL); CMyString(const CMyString& str); ~CMyString(void); CMyString& operator = (const CMyString& str);private: char* m_pData;}; 请实现其赋值运算符的重载函数,要求异常安全,即当对一个对象进行赋值时发生异常,对象的状态不能改变。 56.最长公共字串。 题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中, 则字符串一称之为字符串二的子串。 注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。 请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。 例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串, 则输出它们的长度4,并打印任意一个子串。 分析:求最长公共子串(Longest Common Subsequence, LCS)是一道非常经典的动态规划题, 因此一些重视算法的公司像MicroStrategy都把它当作面试题。 57.用俩个栈实现队列。 题目:某队列的声明如下: templateclass CQueue { public: CQueue() {} ~CQueue() {} void appendTail(const T& node); // append a element to tail void deleteHead(); // remove a element from headprivate: T>m_stack1; T>m_stack2;}; 分析:从上面的类的声明中,我们发现在队列中有两个栈。 因此这道题实质上是要求我们用两个栈来实现一个队列。 相信大家对栈和队列的基本性质都非常了解了:栈是一种后入先出的数据容器, 因此对队列进行的插入和删除操作都是在栈顶上进行;队列是一种先入先出的数据容器, 我们总是把新元素插入到队列的尾部,而从队列的头部删除元素。 58.从尾到头输出链表。 题目:输入一个链表的头结点,从尾到头反过来输出每个结点的值。链表结点定义如下: struct ListNode { int m_nKey; ListNode* m_pNext;}; 分析:这是一道很有意思的面试题。 该题以及它的变体经常出现在各大公司的面试、笔试题中。 59.不能被继承的类。 题目:用C++设计一个不能被继承的类。 分析:这是Adobe公司2007年校园招聘的最新笔试题。 这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目。 60.在O(1)时间内删除链表结点。 题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下: struct ListNode { int m_nKey; ListNode* m_pNext;}; 函数的声明如下: void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted); 分析:这是一道广为流传的Google面试题,能有效考察我们的编程基本功,还能考察我们的反应速度, 更重要的是,还能考察我们对时间复杂度的理解。 61.找出数组中两个只出现一次的数字 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。 分析:这是一道很新颖的关于位运算的面试题。 62.找出链表的第一个公共结点。 题目:两个单向链表,找出它们的第一个公共结点。 链表的结点定义为: struct ListNode { int m_nKey; ListNode* m_pNext;}; 分析:这是一道微软的面试题。微软非常喜欢与链表相关的题目, 因此在微软的面试题中,链表出现的概率相当高。 63.在字符串中删除特定的字符。 题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”, 则删除之后的第一个字符串变成”Thy r stdnts.”。 分析:这是一道微软面试题。在微软的常见面试题中,与字符串相关的题目占了很大的一部分, 因为写程序操作字符串能很好的反映我们的编程基本功。 寻找丑数。题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数, 但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。 求按从小到大的顺序的第1500个丑数。 分析:这是一道在网络上广为流传的面试题,据说google曾经采用过这道题。 65.输出1到最大的N位数 题目:输入数字n,按顺序输出从1最大的n位10进制数。比如输入3, 则输出1、2、3一直到最大的3位数即999。 分析:这是一道很有意思的题目。看起来很简单,其实里面却有不少的玄机。 66.颠倒栈。 题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。 颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。 67.俩个闲玩娱乐。 1.扑克牌的顺子 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。 2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。 2.n个骰子的点数。 把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n, 打印出S的所有可能的值出现的概率。 68.把数组排成最小的数。 题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。 例如输入数组{32, 321},则输出这两个能排成的最小数字32132。 请给出解决问题的算法,并证明该算法。 分析:这是09年6月份百度的一道面试题, 从这道题我们可以看出百度对应聘者在算法方面有很高的要求。 69.旋转数组中的最小元素。 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转, 输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。 分析:这道题最直观的解法并不难。从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N)。但这个思路没有利用输入数组的特性,我们应该能找到更好的解法。 70.给出一个函数来输出一个字符串的所有排列。 ANSWER 简单的回溯就可以实现了。当然排列的产生也有很多种算法,去看看组合数学, 还有逆序生成排列和一些不需要递归生成排列的方法。 印象中Knuth的第一卷里面深入讲了排列的生成。这些算法的理解需要一定的数学功底, 也需要一定的灵感,有兴趣最好看看。 71.数值的整数次方。 题目:实现函数double Power(double base, int exponent),求base的exponent次方。 不需要考虑溢出。 分析:这是一道看起来很简单的问题。可能有不少的人在看到题目后30秒写出如下的代码: double Power(double base, int exponent) { double result = 1.0; for(int i = 1; i<= exponent; ++i) result *= base; return result;} 题目:设计一个类,我们只能生成该类的一个实例。 分析:只能生成一个实例的类是实现了Singleton模式的类型。 73.对策字符串的最大长度。 题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。 比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。 分析:可能很多人都写过判断一个字符串是不是对称的函数,这个题目可以看成是该函数的加强版。 74.数组中超过出现次数超过一半的数字 题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。 分析:这是一道广为流传的面试题,包括百度、微软和Google在内的多家公司都 曾经采用过这个题目。要几十分钟的时间里很好地解答这道题, 除了较好的编程能力之外,还需要较快的反应和较强的逻辑思维能力。 75.二叉树两个结点的最低共同父结点 题目:二叉树的结点定义如下: struct TreeNode { int m_nvalue; TreeNode* m_pLeft; TreeNode* m_pRight;}; 输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。 分析:求数中两个结点的最低共同结点是面试中经常出现的一个问题。这个问题至少有两个变种。 76.复杂链表的复制 题目:有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外, 还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下: struct ComplexNode { int m_nValue; ComplexNode* m_pNext; ComplexNode* m_pSibling;}; 下图是一个含有5个结点的该类型复杂链表。 图中实线箭头表示m_pNext指针,虚线箭头表示m_pSibling指针。为简单起见, 指向NULL的指针没有画出。 请完成函数ComplexNode* Clone(ComplexNode* pHead),以复制一个复杂链表。 分析:在常见的数据结构上稍加变化,这是一种很新颖的面试题。 要在不到一个小时的时间里解决这种类型的题目,我们需要较快的反应能力, 对数据结构透彻的理解以及扎实的编程功底。 77.关于链表问题的面试题目如下: 1.给定单链表,检测是否有环。 使用两个指针p1,p2从链表头开始遍历,p1每次前进一步,p2每次前进两步。如果p2到达链表尾部, 说明无环,否则p1、p2必然会在某个时刻相遇(p1==p2),从而检测到链表中有环。 2.给定两个单链表(head1, head2),检测两个链表是否有交点,如果有返回第一个交点。 如果head1==head2,那么显然相交,直接返回head1。否则,分别从head1,head2开始遍历两个链表获得其长度len1与len2,假设len1>=len2, 那么指针p1由head1开始向后移动len1-len2步,指针p2=head2, 下面p1、p2每次向后前进一步并比较p1p2是否相等,如果相等即返回该结点, 否则说明两个链表没有交点。 3.给定单链表(head),如果有环的话请返回从头结点进入环的第一个节点。 运用题一,我们可以检查链表中是否有环。 如果有环,那么p1p2重合点p必然在环中。从p点断开环,方法为:p1=p, p2=p->next, p->next=NULL。此时,原单链表可以看作两条单链表, 一条从head开始,另一条从p2开始,于是运用题二的方法,我们找到它们的第一个交点即为所求。 4.只给定单链表中某个结点p(并非最后一个结点,即p->next!=NULL)指针,删除该结点。 办法很简单,首先是放p中数据,然后将p->next的数据copy入p中,接下来删除p->next即可。 5.只给定单链表中某个结点p(非空结点),在p前面插入一个结点。 办法与前者类似,首先分配一个结点q,将q插入在p后,接下来将p中的数据copy入q中, 然后再将要插入的数据记录在p中。 78.链表和数组的区别在哪里? 分析:主要在基本概念上的理解。 但是最好能考虑的全面一点,现在公司招人的竞争可能就在细节上产生, 谁比较仔细,谁获胜的机会就大。 1.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法? 2.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法? 3.请编写能直接实现strstr()函数功能的代码。 80.阿里巴巴一道笔试题 问题描述:【深入解析面试必备:算法与数据结构核心问题】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于找到了!准备面试算法和数据结构的时候感觉很茫然,这个帖子太及时了
有14位网友表示赞同!
面试官总是会问各种奇奇怪怪算法题吧,刷这类型的题目可以提升逻辑思维能力哦
有8位网友表示赞同!
学习数据结构的重点是什么呢?我一直在摸索着...
有19位网友表示赞同!
想问问有没有人总结过常见的面试算法题分类?
有16位网友表示赞同!
最近开始准备面试,感觉算法和数据结构是重点了!
有9位网友表示赞同!
以前从来没有接触过这方面知识,这份帖子正好可以帮我入门
有20位网友表示赞同!
分享一下你们在刷题过程中的经验吧,有哪些网站或者书籍推荐?
有20位网友表示赞同!
面试算法真的太考验人脑的受力能力了!
有8位网友表示赞同!
这个帖子的收藏地址我得要记下来,总会有用!
有18位网友表示赞同!
数据结构好像学起来特别深奥...
有9位网友表示赞同!
感觉算法题是需要一点技巧才会解开的。
有5位网友表示赞同!
分享一些刷题的小技巧吧!我很想提高效率学习
有20位网友表示赞同!
想要在面试中表现好,算法和数据结构就是必备技能啊!
有9位网友表示赞同!
有没有人遇到过什么比较有趣的面试题?记得说一下是怎么解决的!
有17位网友表示赞同!
这个帖子真是我的福音!准备面试的时候可以参考一下
有8位网友表示赞同!
希望以后能够掌握这方面的知识,这样才能自信的面试
有6位网友表示赞同!
学习算法和数据结构是件长久的事,需要坚持练习
有5位网友表示赞同!
这份文章真是太详细了,感谢作者的贡献!
有5位网友表示赞同!
这种题目感觉很有挑战性,也挺有趣!
有12位网友表示赞同!