1.如下为类型CMyString的声明,请为该类型添加赋值运算符函数。
3.在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否函数该整数。
右上角开始
4.请实现一个函数,把字符串中的每个空格替换成”%20”。例如输入”We are happy”,则输出”We%20are%20happy”。
两个指针,从后往前。复杂度从O(n2)到O(n).
4_1.有两个排序的数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2。请实现一个函数,把A2中的所有数字插入到A1中并且所有的数字是排序的。
从尾到头复制
5.从尾到头打印链表
std::stack<ListNode *>nodes;
用栈,不改变原链表。
6.输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
前序第一个节点为根节点,利用该点切分中序,递归
7_1.用两个队列实现一个栈。
正常压入,pop的时候,把队列全移动到另一个队列
8_-1.快排的Partition函数 掌握!
8_-2.公司几万员工年龄排序!
8.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
两个指针二分法缩小范围(有两个陷阱记住)
9.写一个函数,输入n,求斐波那契数列的第n项。
不递归,两两计算
9_1 青蛙跳台阶,
9_2 2x1覆盖2x8
10.请实现一个函数,输入一个整数,输出该二进制表示中1的个数。
n=n&(n-1),count++
10_1.用一条语句判断一个整数是不是2的整数次方。
一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他所有位都是0。根据前面的分析,把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0。
10_2.输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。比如10的二进制表示为1010,13的二进制表示为1101,需要改变1010中的3位才能得到1101 。 两步:第一步求这两个数的异或,第二步统计异或结果中1的位数。
10_3.把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于是把整数的二进制表示中的最右边一个1变成0。很多二进制的问题都可以用这个思路解决。
11.实现函数double Power(double base,int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
需考虑指数小于0情况,所给数是0的情况。
不能直接利用等号(==)判断两个小数是否相等。
12.输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999 。
(需考虑n很大的情况)用字符串代表数字
12_1.如果面试题关于n位的整数并且没有限定n的取值范围,或者是输入任意大小的整数,那么这个题目很有可能是需要考虑大数问题的,字符串是一个简单,有效的表示大数的方法。
13.给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该节点。链表的节点与函数的定义如下:
把节点j的内容复制覆盖节点i,接下来再把节点i的m_pNext指向j的下一个节点之后删除结点j。这种方法不用遍历链表上结点i前面的节点,只需要有指向i结点的指针即可完成操作。
如果删除结点是尾结点,则需要从头遍历。
14.调整数组顺序使奇数位于偶数前面。
首尾两个指针,swap
15.求链表倒数第K个结点,
快慢指针
15_1.求链表的中间结点,
一个指针走1步,一个指针走2步,快的到结尾,慢的到中间
15_2.单向链表是否形成了环形结构。
一个指针走1步,一个指针走2步,快的追上慢的,则是环形
16.反转链表
pPre,pNode, pNext(代码要会写)
17.输入两个递增排序的链表,合并这两个链表并使新链表中结点仍然是按照递增排序的。
递归
18.输入两颗二叉树A和B,判断B是不是A的子结构。:
bool HasSubTree(BiTNode * pRoot1, BiTNode * pRoot2)
bool DoesTree1HaveTree2(BiTNode * pRoot1, BiTNode * pRoot2) (递归)
19.请完成一个函数,输入一个二叉树,该函数输出它的镜像。
交换左右子树,递归(代码只有几行)
20.顺时针打印矩阵
4步。左右,上下,右左,下上。
21.定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调用min、push以及pop的时间复杂度都是O(1)。
定义辅助栈。辅助栈栈顶一直维持最小数据。
22.给出栈的压入顺序,判断另一数组是否为弹出顺序。
如果下一个弹出的数字刚好是栈顶数字,弹出,如果下一个弹出的数字不在栈顶,把还没入栈的数字压入辅助栈,直到下一个要弹出的数字压入栈顶为止。
23.从上到下打印二叉树-层序遍历。
队列,头部取节点,儿子放后面
24.二叉搜索树的后序遍历序列
序列最后一个数字是根结点,把序列分为两部分,小于它的是左子树,大于它的是右子树,递归。
25.打印二叉树结点和为输入整数的所有路径。
前序+栈(用vector实现)+回退pop
26.复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。
ABC->AABBCC
27.输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
中序遍历,pLastNodeInList指向已经转换好的链表的最后一个结点。左、右都转换成排序的双向链表再和根结点链接起来,递归。
28.输入一个字符串,打印出该字符串中字符的所有排列。
分两部分,求第二部分的排列;再与首字母交换
28_1.输入一个含有8个数字的数组,判断有没有可能把这8个数分别放在立方体8个顶点上,使得正方体上三组相对的面上4个顶点和都相等。
a1,a2,a3,a4,a5,a6,a7,a8全排列,然后判断有没有
a1+a2+a3+a4=a5+a6+a7+a8,a1+a3+a5+a7=a2+a4+a6+a8,a1+a2+a5+a6=a3+a4+a7+a8.
28_2.8X8国际象棋放8个皇后,使其不能互相攻击。即任意两个皇后不能在同一行,同一列,同一对角线。有多少种符合的摆法。
a[8],数组表示第i个数字表示位于第i行的皇后列号,用0-7初始化。全排列。只要判断是否对角线:i-j=a[i]-a[j]或者j-i=a[i]-a[j].
29.数组中次数超过一半的数字
1、Partition,取中位数 O(n)
2、保存当前数字和次数,下一个数字同,次数+1,不同,次数-1。次数为0,保存下一个数字。 O(n)
复杂度都是O(n),第一种会修改原数组,第二种不会。
30.输入n个整数,找出其中最小的k个数。
1、Partition,取index=k-1的左边的数 O(n)
2、用最大堆或红黑树实现 O(logk) 适合海量数据
31.求正负整数数组中所有子数组的和的最大值。
设置累加和,顺序累加,和为负数则抛弃,实时更新和最大值(动态规划)
32.求从1到n这n个整数中1出现的次数。
每次去掉最高位然后递归,分解例如21345 1-1345 1346-21345 O(logn)
33.输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出所有数字中最小的一个。例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323。
用库函数qsort排序,重定义排序标准。
34.我们把只包含因子2,3和5的数称作丑数。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做第一个丑数。
创建数组保存已找丑数,空间换时间。求已有丑数乘2,乘3,乘5三个数的最小值为新丑数,T2,T3,T5指针指向丑数位置,每次生成新丑数,更新指针位置。
35.在字符串中找出第一个只出现一次的字符。如输入”abaccdeff”,则输出’b’。
哈希表(int hashTable[256]),二次遍历.每次更新字符时间为O(1),第一次扫描时间复杂度为O(n),第二次扫描找出1次的也是O(n),总的是O(n).
35_1.两个字符串,从第一个字符串中删掉第二个字符串出现的所有字符。
创建一个用数组实现的哈希表存储第二个字符串,扫描第一个字符串,O(1)时间就能判断该字符串是不是出现在第二个字符串中。复杂度为O(n).
35_2.删除字符串中所有重复出现的字符。
用布尔型数组实现哈希表,用O(1)时间可以判断字符是否前面已出现,总时间复杂度O(n).
35_3.两个单词出现的字母相同,并且每个字母出现次数也相同,互称为变位词。如silent与listen.完成一个函数判断两个词是不是互为变位词。
用一个数组实现哈希表,统计第一个字符串的每个字符,再扫描第二个字符串,每次-1,扫描完第二个结束后,哈希表所有值为0,两个字符串互为变位词。
36.在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
–归并排序
37.输入两个单向链表,找出它们的第一个公共结点。
一:两个栈,从后往前找,空间、时间复杂度O(m+n)
二:先遍历两个链表,第二次遍历长的比短的先走(m-n)步,然后一起遍历,第一个相同的就是。时间复杂度O(m+n)。
38.统计一个数字在排序数组中出现的次数。
二分查找,递归找到第一个K和最后一个K的位置,相减。
39.二叉树深度,
递归,代码三行。
39_1.是否平衡二叉树
递归,保存深度
40.一个整型数组里除了两个数字之外,其他的数字都出现了两次。
异或消除相等,是否跟异或结果最高位1一样,分成两个数组,得到两个数。
41.输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。
直观想法O(n*n),前后指针O(n).
41_1.输入一个整数s,打印出所有和为s的连续正数序列。
前后指针,和大于s,减去small,小于s,加上big。一直到(1+s)/2.
42.输入一个英文句子,翻转句子中单词的顺序
整个句子翻转,然后每个词翻转。
42_1.字符串的左旋转。如”abcdefg”和2,左旋转后为”cdefgab”.
翻转三次。以n为分割线,翻转0->(n-1),n->(length-1),0-(length-1).
43.把n个骰子仍在地上,所有骰子朝上一面的点数之和为s,输入n,打印出s的所有可能的值出现的概率。
44.从扑克牌中随机抽5张牌,判断是不是一个顺子,大、小王可以看成任意数字。
排序,补大小王
45.0~n-1这n个数字排列成一个圆圈,从数字0开始每次从这个圆圈中删除第m个数字。求出这个圆圈里剩下的最后一个数字。
环形链表or递归f(n,m)=f(n-1,m)+m
46.求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句。
构造函数、虚函数、函数指针、模板类型
47.写一个函数,求两个整数之和,要求函数体内部的使用+、-、*、\四则运算符号。
位运算,异或求加,与运算求进位。
48.不能被继承的类
构造函数设为私有or 虚拟继承
49.把字符串转换为整数
注意考虑NULL,空字符串,正负号等.
50.树中两个结点的最低公共祖先
1、如果是二叉搜索树,那从根结点依次找到的第一个在两个输入结点的值之间的结点就是。
2、不是二叉搜索树,如果有指向父结点的指针,那就转换为求两个链表的第一个公共结点。
3、不是二叉搜索,也没有指向父结点指针,用辅助内存保存路径。判断两个路径。
51.数组中重复的数
利用下标交换存储,第一个重复的数字。