牛客网(剑指offer)
NickChen_0411
学生
展开
-
64.滑动窗口的最大值
题目描述给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,...原创 2018-06-10 13:24:09 · 201 阅读 · 0 评论 -
48.不用加减乘除做加法
题目描述写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。思路:采用 按位与再左移一位、按位异或 模拟 加法的进位和对应位相加。首先看十进制是如何做的: 5+7=12,三步走第一步:相加各位的值,不算进位,得到2。第二步:计算进位值,得到10. 如果这一步的进位值为0,那么第一步得到的值就是最终结果。第三步:重复上述两步,只是相加的值变成上述两步的得到的结果2和10,得...原创 2018-05-22 16:25:00 · 150 阅读 · 0 评论 -
47.求1+2+3+...+n
题目描述求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。思路:采用函数递归,return n + f(n - 1);用n的数值和&&运算作为判断条件;代码:class Solution {public: int Sum_Solution(int n) { int ...原创 2018-05-22 16:02:51 · 1187 阅读 · 0 评论 -
52.正则表达式匹配
题目描述请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配思路:首先处理两个指针均属于NULL,此时返回true;其次进行字符串的判断流程,关键点是判断当...原创 2018-05-26 12:21:57 · 199 阅读 · 0 评论 -
51.构件乘积数组
题目描述给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法无效思路:采用动态规划的思路,构建二位dp[i][j]数组,表示从第Ai乘到Aj的结果,但该方法时间复杂度为O(N*N),空间复杂度为O(N*N),非常不理想,还不如直接暴力求解,因此舍弃。有...转载 2018-05-25 16:33:45 · 175 阅读 · 0 评论 -
46.孩子们的游戏(圆圈中最后剩下的数)
题目描述每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去.......原创 2018-05-21 15:54:11 · 269 阅读 · 0 评论 -
41.和为S的连续正数序列
题目描述小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!输出描述:输出所有和为S的连续正数序列。序列内按...原创 2018-05-14 17:04:23 · 148 阅读 · 0 评论 -
36.两个链表的第一个公共节点
题目描述输入两个链表,找出它们的第一个公共结点。思路:用一个unordered_set记录已访问的链表的地址,第一个重复出现的地址,即为第一个公共结点代码:/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {...原创 2018-05-07 11:11:07 · 326 阅读 · 0 评论 -
39.平衡二叉树
题目描述输入一棵二叉树,判断该二叉树是否是平衡二叉树。思路:平衡二叉树只满足树的平衡,但它不一定是排好序的二叉搜索树,因此在这里可以采用递归的方式,从叶子结点向根节点搜索,若发现有父节点的左右节点深度相差大于1,则返回false,若无则返回true,继续遍历,知道达到根节点。代码:class Solution {public: bool IsBalanced_Solution(TreeN...原创 2018-05-11 23:04:19 · 166 阅读 · 0 评论 -
40.数组中只出现一次的数
题目描述一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。思路一:用一个unordered_set容器作为辅助(不用vector容器是因为unordered_set的查找操作时间复杂度为O(1)),初始时容器内无任何数,一层循环遍历data数组,当容器内无data[i]时,则放入容器,有则在容器内删除该数,最终容器内剩余的两个数即为最终所求结果。代码一:c...原创 2018-05-11 22:53:29 · 142 阅读 · 0 评论 -
35.数组中的逆序对
题目描述在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007输入描述:题目保证输入的数组中没有的相同的数字数据范围: 对于%50的数据,size<=10^4 对于%75的数据,size<=10^5 对于%100的数据,size<=2...原创 2018-05-05 16:21:52 · 169 阅读 · 0 评论 -
49.把字符串转成整数
题目描述将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0输入描述:输入一个字符串,包括数字字母符号,可以为空输出描述:如果是合法的数值表达则返回该数字,否则返回0示例1输入+2147483647 1a33输出2147483647 0思路:设置一个check函数,判断该字符是否为数字;对字符串的首个字符进行判断,若为‘+’...原创 2018-05-04 16:35:07 · 310 阅读 · 0 评论 -
34.第一个只出现一次的字符
题目描述在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置;若无,则返回-1.思路:用一个vector<pair<char, int>>来保存字符出现的先后顺序,以及其索引位置,并用一个int check[128]来保存字符出现的次数(ASCII码索引范围是0-127),循环两次,第一次统计信息,第二次输出...原创 2018-05-04 12:27:10 · 126 阅读 · 0 评论 -
32.把数组排成最小的数
题目描述输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。思路:每次从vector中找出最小的数,并将其erase,直到vector为空;在找寻最小的数时,设计一个比较函数checkmin(),先比较前面的部分,超出部分与较短字符串的首字符比较,即可得到比较结果,代码如下:...原创 2018-05-04 11:05:26 · 193 阅读 · 0 评论 -
44.翻转单词顺序列
题目描述牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?思路一:以空格为分隔符,将单...原创 2018-05-16 23:13:27 · 156 阅读 · 0 评论 -
30.连续子数组的最大和
题目描述HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至...原创 2018-05-02 17:58:22 · 158 阅读 · 0 评论 -
58.对称的二叉树
题目描述请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。思路一(递归版)构建一个bool heler(TreeNode* l, TreeNode* r)函数,用来判断传入的两个指针所对应的结点是否相等,若同为空,则返回true,若一个存在一个为空,或对应值不相等,则返回false,若对应值相等,则递归调用,返回helper(l->...原创 2018-06-03 17:03:43 · 190 阅读 · 0 评论 -
42.和为S的两个数
题目描述输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。输出描述:对应每个测试案例,输出两个数,小的先输出。思路:同样是使用左右指针(因为数组是递增排序的),调试时发现,需要考虑到没有满足条件的情况。代码:class Solution {public: vector<int> FindNumber...原创 2018-05-16 21:30:00 · 164 阅读 · 0 评论 -
57.二叉树的下一个结点
题目描述给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。思路:由于是中序遍历二叉树,因此需要分析当前结点是否含有右子树;若有,则返回右子树的最底层左孩子结点;若没有,则向上找父节点,找到最近的一个满足其父节点的左子树是其本身的节点;若找父节点直到root还没找到,则返回NULL。如图所示:代码:/*struct...转载 2018-06-01 15:18:38 · 292 阅读 · 0 评论 -
63.数据流中的中位数
题目描述如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。思路:构造一个最大堆和一个最小堆,最大堆用来存放较小的那一半的数据,最小堆用来存放较大的那一半的数据,每次插入数据时与最大堆的堆顶进行比较,若比其小或相等,则插入最大堆,反之插入最小堆;插入数据后需要平衡两...原创 2018-06-08 11:53:48 · 1342 阅读 · 0 评论 -
62.二叉搜索树的第k个结点
题目描述给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。思路:采用先序遍历,引入参数k和res,前者用来记录取到还剩几个数,后者用来保存最后的结点。代码:/*struct TreeNode { int val; struct TreeNode *left; struct Tre...原创 2018-06-07 16:27:36 · 150 阅读 · 0 评论 -
56.删除链表中重复的结点
题目描述在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5思路一(非递归):先设置一个虚拟结点dummy,使dummy->next = pHead,设置last指针指向dummy,令指针p从链表头开始遍历,当p和p->...原创 2018-05-31 11:10:36 · 201 阅读 · 0 评论 -
61.序列化二叉树
题目描述请实现两个函数,分别用来序列化和反序列化二叉树思路一:选用vector<int> arr作为辅助,最后转为int* 和char* 的数据类型,由于‘#’不方便表示,因此用一个不会出现的数0x23333代替。方法上是使用递归的先序遍历。代码一:/*struct TreeNode { int val; struct TreeNode *left; stru...转载 2018-06-06 17:37:46 · 540 阅读 · 1 评论 -
55.链表中环的入口结点
题目描述一个链表中包含环,请找出该链表的环的入口结点。思路一:使用一个集合unordered_set<ListNode*>来保存已经访问过的结点,当第一次访问到已经被访问过的结点时,即为环的入口结点,此方法需要额外的空间进行辅助。代码一:/*struct ListNode { int val; struct ListNode *next; ListNode(i...原创 2018-05-30 20:13:54 · 323 阅读 · 0 评论 -
54.字符流中第一个不重复的字符
题目描述请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。输出描述:如果当前字符流没有存在出现一次的字符,返回#字符。思路一:用一个辅助队列和辅助计数数组,在顺序读取字符串时,按顺序存储出现的字符,并计数;最后返回第一个只出现一次的单个字...原创 2018-05-29 16:54:15 · 207 阅读 · 0 评论 -
60.把二叉树打印成多行
题目描述从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。思路一:利用层次遍历二叉树的方式,用一个队列进行辅助,每次打印前取n = q.size(),可以保证逐行打印。代码一:/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int...原创 2018-06-05 11:08:06 · 469 阅读 · 0 评论 -
53.表示数值的字符串
题目描述请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。思路一:设定符号、小数点、e是否出现的标志变量,依次从e原创 2018-05-28 21:34:49 · 194 阅读 · 0 评论 -
66.机器人的运动范围
题目描述地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?思路一(DFS):采用深度优先遍历,只从(0, ...原创 2018-06-11 15:36:33 · 200 阅读 · 0 评论 -
65.矩阵中的路径
题目描述请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了...原创 2018-06-11 14:46:31 · 185 阅读 · 0 评论 -
59.按之字形顺序打印二叉树
1.思路:层次遍历二叉树,其中用变量size来确定每一层中结点的个数,定义bool变量even来确定是第几层,若是偶数层,则将数组内的数进行颠倒,再存入二维数组中。2.代码:/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : ...原创 2018-06-04 12:34:08 · 341 阅读 · 0 评论 -
50.数组中重复的数字
题目描述在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。思路一:采用辅助数组arr,对已出现的数进行标记;时间复杂度、空间复杂度均为O(N)。代码一:class Solution {...原创 2018-05-23 15:44:35 · 186 阅读 · 0 评论 -
43.左旋转字符串
题目描述汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!思路:首先找到旋转后指针所在的初始位置,从初始位置开始,依次往后遍历,将字符复制给字符串res;注意字...原创 2018-05-16 22:06:13 · 118 阅读 · 0 评论 -
31.整数中1出现的次数(从1到n整数中1出现的次数)
题目描述求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。思路:按位进行分析1出现次数,分三种情况,a的末位是0,1,>=2代码:class Solution {...原创 2018-05-02 17:55:03 · 183 阅读 · 0 评论 -
38.二叉树的深度
题目描述输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。思路:DFS,递归解法,方法简单;BFS,非递归解法,用队列进行辅助,注意每次取q.size()作为该层节点的个数,进行for循环遍历,之后对res加1;代码(DFS):/*struct TreeNode { int val; struct TreeNode *le...原创 2018-05-08 21:11:16 · 124 阅读 · 0 评论 -
16.合并两个排序的链表
1.思路:双指针法,判断当前指针指向的两个数,将较小的数放入新链表中,选取的指针往后移位,直到到达NULL。需要注意的是,在对指针的使用时,若给的是两个相等的未赋值的野指针,则它们不是互相独立的,一个发生变化时另一个也会接着一起变,因此这里需要新建一个ListNode结点,先将两个指针指向结点,再做操作。2.代码一(非递归):/*struct ListNode { int原创 2018-01-10 12:09:24 · 283 阅读 · 0 评论 -
15.反转链表
1.思路: 老方法,但一定要记住需要定义三个指针,head, pre, cur;并需要判断链表是否为空。2.代码:/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {原创 2018-01-10 11:18:22 · 247 阅读 · 0 评论 -
14.链表中倒数第k个结点
1.思路: 定义一个start和end指针,使其之间相差k个结点,令它们同时往后移动,当end到达链表末尾时,start所指即为链表中倒数第k个结点。需要注意的是要讨论链表是否存在倒数第k个结点,即链表长度是否大于k,若不存在,应及时停止并返回NULL。2.代码:struct ListNode { int val; struct ListNode *next; ListNo原创 2018-01-10 10:42:45 · 194 阅读 · 0 评论 -
13.调整数组顺序使奇数位于偶数前面
1.思路:遍历一次待排序数组,用int start记录已排序好的最后一个奇数的下标,当遍历到奇数时,使用类似于冒泡的方式,将奇数移动至下标start处,以保证偶数间的相对顺序不发生变化,然后++start。2.代码:class Solution {public: void swape(vector &array, int i, int j) { int原创 2018-01-07 18:03:00 · 218 阅读 · 0 评论 -
12.数值的整数次方
1.思路:采用二分法和分治的思想,将指数运算分解成两个指数运算的乘积,这里需要考虑指数的奇偶性;在计算时,还应考虑指数的正负性。2.代码:class Solution {public: double Power(double base, int exponent) { if(exponent < 0) { base = 1.0/原创 2018-01-07 17:46:57 · 227 阅读 · 0 评论 -
11.二进制中1的个数
1.思路:由于负数用的是补码表示,因此先判断n的正负性,正数则一位一位判断是否为1,负数则先用 n = -n - 1,将其转换为各个位取反后的正数,再算1出现的次数,最后用总位数32减去1出现的个数即可(注意此处不能直接统计0的个数,因为while循环会提前停止)。2.代码:class Solution {public: int NumberOf1(int n)原创 2018-01-07 17:12:26 · 270 阅读 · 0 评论