《剑指Offer》
文章平均质量分 51
lskyne
这个作者很懒,什么都没留下…
展开
-
面试题4:替换空格
题目:请实现一个函数,把字符串中的每个空格替换成“%20”,例如:"we are happy”替换成“we%20are%20happy”思路1,没遇到一个空格,将其后所有字符往后移位,时间复杂度较高O(n^2),不可取2,先统计空格个数,确定新字符串长度,如何从后往前,逐个替换字符,将其移到最终位置,时间复杂度O(n)源程序#include #include #includ原创 2013-06-12 10:49:55 · 942 阅读 · 0 评论 -
面试题29:数组中出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,5,4,2}。由于数字2在数组中出现了5词,超过数组长度的一半,因此输出2.思路:1,如果对数组排序,那么n/2对应的数一定是超过一半的数字(前提是存在这个数字),即长度为n的数组中第n/2大的数字,O(n)2,根据数组特点,数组中一个数组出现的次数超过数组长度的一半,即原创 2013-07-17 21:43:15 · 5607 阅读 · 2 评论 -
面试题31:连续子数组的最大和
题目:输入一个整形数组,数组里有源代码:#include "stdio.h"int MaxSumSubArray(int *data,int len){ int sum =0; int great=0; for(int i=0;i<len;i++) { if(sum<0) { sum=data[i]; } else { s原创 2013-07-18 09:02:25 · 948 阅读 · 0 评论 -
面试题22:从上往下打印二叉树
题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印,例如 8 6 105 7 9 11依次打印:8,6,10,5,7,9,11理解:层次遍历二叉树,借助队列,先将根入队列,根出列,打印根的值,并把根的左孩子和右孩子入队列,再出列,打印,入列(根的左孩子的 左孩子和右孩子),.......二叉树结点的定义:str原创 2013-07-02 21:37:31 · 6099 阅读 · 0 评论 -
面试题33:把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数。打印能拼接处的所有数字钟最小的一个。例如输入数组{3,32,321},则打印出这3个数字能排成的最凶啊数字321323.思路:1,传统:数组全排列,再排序2,定义排序规则,将整数转化成字符数组,两个字符数组比较大小的比较函数要重新定义,(a+b)与(b+a)的大小确定先后顺序。由小到大最后依次输出各个字符数组。伪代码原创 2013-07-18 15:09:13 · 3390 阅读 · 0 评论 -
面试题30:最小的k个数
题目:输入n个整数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4.思路1,同29题一样,利用快排思想,醉倒第k大的数,它左边都比它小即可。O(n)2,适合海量数据,利用堆数据结果,取数O(1),删除和插入需要O(k),总共n个数,时间复杂度O(nlogk)要做三件事:a,在k个整数中找到最大数;b,有可能在这个容器原创 2013-07-17 21:49:19 · 1030 阅读 · 0 评论 -
面试题20:顺时针打印矩阵 ***
题目:输入一个矩阵,按照从外向里以顺时针的顺序一次打印出每个数字,例如1 2 3 4 5 6 7 8 9 10 11 1213 14 15 16则一次打印出数字:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10关键:看起来比较复杂,分清思路,先整体后局部分析源代码#include "stdio.h"#include "s原创 2013-06-28 00:17:02 · 1047 阅读 · 0 评论 -
面试题36:数组中的逆序列 ****
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。思路:利用归并排序思想,将序列不断分割,对每个部分计算逆序数,并排序,每个部分之间再进行比较,同时记录逆序对。源代码:#include "stdio.h"int InversePairsCore(int* data,int* copy,int star原创 2013-07-20 21:19:06 · 1864 阅读 · 0 评论 -
面试题34:丑数
题目:我们把只包含因子2,3,和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6,8都是丑数,但14不是,因为它包含因子7,习惯上我们把1当做第一丑数。思路:1,传统方法,一个数一个数判断2,第一种方法效率太低,主要是不是丑数也需要花费时间进行判断。我们可以把丑数看做一个数组,另p2,p3,p5为指向数组某个丑数的指针。因为下一个丑数一定是由前面的原创 2013-07-20 16:34:25 · 958 阅读 · 0 评论 -
面试题35:第一个只出现一次的字符
题目:在字符串中中找到第一个只出现一次的字符。如输入“abaccdeff”,则输出'b'。思路:利用hash表,遍历一遍,并记录次数,hash表自己构建,一个字符8bit,最大为256,所以可设hashTable[256];源代码:#include "stdio.h"char FirstNotRepeat(char *ch){ if(ch == NULL) return '\原创 2013-07-20 21:37:32 · 1017 阅读 · 0 评论 -
面试题44:扑克牌的顺子
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成是任意数字。思路:1,首先把数组排序,然后统计数组中0的个数和数组中不连续数之间的距离。如果空缺距离小于或者等于0的个数,则是连续的。否则是非连续的。2,判断条件a,数组为空b,长度《1c,相同数字不连续(重要)代码:#原创 2013-08-27 10:30:20 · 1941 阅读 · 0 评论 -
面试题40:数组中只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是 O(n),空间复杂度是O(1)。思路:如果只有一个只出现一次的数字,通过异或就可以找出。此时有两个出现一次,异或的结果也就是这个两个数的异或。通过异或结果可以把数组分成两部分,这两个孤立的数字分别落在落在两部分。通过异或结果中,含1的位置,将此位置为0与为1分开成两个数组,再分别原创 2013-08-27 15:01:45 · 1327 阅读 · 0 评论 -
面试题45:圆圈中最后剩下的数字
题目:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求出这个圆圈里剩下的最后一个数字常规思路:主要list的运用代码:#include #include using namespace std;int LastRemaining(unsigned int n,unsigned int m){ if(n<1 || m<1) r原创 2013-08-28 00:14:09 · 1679 阅读 · 0 评论 -
面试题47:不用加减乘除做加法
题目:写一个函数,求两个整数之和,要求在函数体内不得使用+,-,*,/四则运算符号思路:1,先做异或运算2,保留进位数据3,进位左移,与异或结果做“”与“运算4,循环代码:#include "stdio.h"#include "stdlib.h"int Add(int num1,int num2){ int sum,carry; do { sum=num原创 2013-08-28 09:18:34 · 1401 阅读 · 0 评论 -
面试题16:反转链表
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。关键:头指针的返回源代码#include #include typedef struct LNode{ int data; struct LNode *next;}*LinkList;void create_list(LinkList &L,int &n){ LinkList p,q; i原创 2013-06-20 22:10:46 · 754 阅读 · 0 评论 -
面试题28:字符串的排列
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印,abc,acb,bac,bca,cab,cba思路:1,求所有可能出现在第一个位置的字符,即把第一个字符与后面所有的字符交换2,固定第一个字符,求后面所有字符的排列。3,这时候求后面字符排列,做递归,重复1,2原创 2013-07-09 08:54:20 · 912 阅读 · 0 评论 -
面试题14:调整数组顺序使奇树位于偶数前面
题目:输入一个整型数组,实现一个函数来调整该数组中数字的长度,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。关键:考虑扩展性,如,奇数偶数条件换成,是否被3整除思路:时间复杂度O(n),前后一起查找源代码:#include "stdio.h"#include "stdlib.h"#include "string.h"void reverse(int *p,i原创 2013-06-20 20:56:28 · 949 阅读 · 0 评论 -
面试题5:从尾到头打印链表
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值思路:1,栈,根据面试官需要是否要改变链表结构2,递归,原理用到栈3,可以改变链表结构,就把链头变链尾,改变指针方向源程序#include #include #include "stack.h"//尾插法建立链表void create_list(LinkList &L){ LinkList p,q; i原创 2013-06-17 09:11:43 · 2640 阅读 · 1 评论 -
面试题3.1--数组与指针大小
声明一个数组,数组的名字也是一个指针,该指针指向数组的第一个元素,也可以用一个指针来访问数组。分析一段代码#include #include int GetSize(int data[]){ return sizeof(data);}int main(){ int data1[]={1,2,3,4,5}; int size1=sizeof(data1); int*原创 2013-06-07 09:48:44 · 942 阅读 · 0 评论 -
面试题3:二维数组中的查找
题目:在一个二维数组中,每一行都按照从左到右的顺序排序,每一列都按照从上到下递增的顺序排序。输入这样的一个数组和一个整数,判断数组中是否含有该整数。原本思路:两个for循环判断,但这样没有考虑到题目要求的递增规则,不符合题意。思路:本题的关键点在于选取开始查找的位置,即矩阵的左上角数或右下角数。如左上角数,查找数先与左上角数进行比较,如果相等,即查找成功,如查找数大于左上角数,则第原创 2013-06-07 10:30:15 · 980 阅读 · 0 评论 -
面试题6:重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。思路:递归建立二叉树源程序:#include "stdio.h"#include "string.h"#include "stdlib.h"typedef struct BiTNode{ char ch; struct BiTNode *lchild,*r原创 2013-06-17 14:11:10 · 1002 阅读 · 0 评论 -
面试题7:用两个栈实现队列
题目:用两个栈实现一个队列,队列的声明如下:请实现它的两个函数appendTrail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。思路两个栈,先进后出,实现先进先出先入一个栈L2,再出栈L2,入另一个栈L1,出栈L1,即可条件保证1,L2为空,L1,不为空2,L2,不为空,L1不为空3,L1,L2为空源代码#include "st原创 2013-06-17 19:54:35 · 740 阅读 · 0 评论 -
面试题8:旋转数组的最小数字 ***
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素,例如数组{3,4,5,1,2}是{1,2,3,4,5}的一个旋转,该数组最小值为1.思路:1,{1,2,3,4,5}不为旋转数组2,根据中间数字判断最小值在前面一半,还是后面一半3,将数组看成一个环,顺时针是递增的,如果中间数大于等于第一个数,则中间数是原创 2013-06-17 21:25:59 · 955 阅读 · 0 评论 -
面试题10:二进制中1的个数
题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数,例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2.思路1,一般做法,对2除法取余,但是效率较低,除法的效率比移位运算低很多,在实际编程中尽可能地用移位运算符代替乘除法2,右移位,当负数时,如0x8000移位结果为0xC000,这样就会造成死循环3,左移位,常规,用标示符1,10,100,100原创 2013-06-18 20:49:18 · 1222 阅读 · 0 评论 -
面试题9:斐波拉契数列
题目:写一个函数,输入n,求斐波拉契(Fibonacci)数列的第n项,斐波拉契定义f(n)= 0 ,n=0 1 ,n=1 f(n-1)+f(n-2) ,n>1思路:1,递归,效率很低 O(n^m)2,循环,实用 O(n)3,数学公式,代码复杂还未完成,效率高,O(logn)源代码#include "stdio.h原创 2013-06-18 01:05:50 · 1300 阅读 · 0 评论 -
面试题11:数值的整数次方
题目:实现函数double Power(double base,int ex),求base的ex次方,不得使用库函数,同时不需要考虑大数问题。目的:主要考察完整性问题,就是尽可能考虑各种输入,并进行异常判断思路:1,base=0,ex2,baes!=0,ex3,base!=0,ex>0源代码#include "stdio.h"#include "stdlib.h"原创 2013-06-18 22:01:38 · 893 阅读 · 0 评论 -
面试题12:打印1到最大的n位数
题目:输入数字n,按顺序打印出从1最大的n位十进制数。例如输入3,则打印出1,2,3,....,一直到最大的3位数即999陷阱:考虑大数问题,就是输入的数字非常大的情况,如100,怎么表示100位的数呢。用字符串保存细节问题1,字符串递增的溢出判断2,打印时过滤0源代码#include "stdio.h"#include "stdlib.h"#include "st原创 2013-06-19 22:53:20 · 1989 阅读 · 0 评论 -
面试题25:二叉树中和为某一值的路径
题目:输入一颗二叉树和一个整数,打印出二叉树中节点值得和为输入整数的所有路径。从熟的根节点开始往下一直到叶节点所经过的节点形成一条路径。如 10 5 124 7二叉树有两条和为22的路径,一条:10-5-7,另一条10-12思路:首先要想到的是通过遍历可以找到所有路径,按照先序遍历的思路,先将经过的左节点入栈,如原创 2013-07-07 11:01:38 · 1784 阅读 · 0 评论 -
面试题13:在O(1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。思路:首先要理解题意,容易误以为是删除值为a的结点,结点指针和头指针都是指向同一个链表,操作1,链表是否含头结点2,链表只有一个结点,结点指针指向它3,结点指针指向链尾,需要顺序遍历,找到结点指针的前一个指针才能进行删除,O(n)4,结点指针不在链尾,O(1),将结点指针下一个指针赋值相同的值,删除原创 2013-06-19 12:45:53 · 891 阅读 · 0 评论 -
面试题15:链表中倒数第k个结点
题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1,2,3,4,5,6.这个链表的倒数第3个结点是值为4的结点。考察点:代码的鲁棒性,如k大于结点数源代码:#include #include typedef struct LNode{ int data;原创 2013-06-20 21:36:10 · 978 阅读 · 0 评论 -
面试题38:数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4.思路:用二分查找,分别找出第一个3,和最后一个3的位置,然后计算个数。时间复杂度O(logn)代码:#include "stdio.h"#include "stdlib.h"int GetFirstK(int* data,int l原创 2013-08-28 10:23:50 · 2571 阅读 · 0 评论