剑指offer
BQW_
吉林大学
北京大学
目前的兴趣:自然语言处理
展开
-
《剑指offer》学习笔记_面试题48_最长不含重复字符的子字符串
题目描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 思路 动态规划。设f(i)表示以第i个字符为结尾的不包含重复字符的子字符串的最长长度。那么当第i个字符之前没有出现过,显然f(i)=f(i-1)+1;当第i个字符出现过,但是两次出现的间隔大于f(i-1),这样前面出现的字符并不影响f(i)的值,因此f(i)=f(i-1)+1;当第i个字...原创 2019-03-13 20:42:41 · 212 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题55(二)_平衡二叉树
题目描述输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左、右子树的深度相差不超过1,那么它就是一棵平衡二叉树。思路后序遍历二叉树,先分别统计左右子树的深度,再判断树是否平衡。C++实现class Solution {public: bool IsBalanced_Solution(TreeNode* pRoot) { retur...原创 2019-03-11 22:34:46 · 209 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题55(一)_二叉树的深度
题目描述 输入一棵二叉树的根节点,求该树的深度。 思路 分治。树的深度等于左右子树中的最大深度加一。 C++实现 class Solution {public: int TreeDepth(TreeNode* pRoot) { if(pRoot==NULL)return 0; int left = TreeDepth(...原创 2019-03-11 22:20:39 · 228 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题53_数字在排序数组中出现的次数
题目描述 统计一个数字在排序数组总出现的次数。 思路 最直观的方法就是顺序扫描,时间复杂度为O(n)。可以使用二分查找,分别找出排序数组中第一个该数的下标和最后一个该数的下标,然后就可得到数字的出现次数。而二分查找的时间复杂度为O(logn)。 C++实现 class Solution {public: int GetNumberOfK(vector<...原创 2019-03-11 22:13:40 · 186 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题52_两个链表的第一个公共节点
题目描述 输入两个链表,找出它们的第一个公共节点。 思路 方法一如果两个链表有公共节点,那么公共节点出现在两个链表的尾部。如果从两个链表的尾部开始向前比较,那么最后一个相同的节点就是我们要找的节点。为了从后向前比较链表,我们可以将链表分别压入两个栈中,然后比较栈顶元素是否相同。如果相同则弹出,如果不同,那么上一个弹出的节点就是我们要找的节点。方法二分别统计两个链表的长...原创 2019-03-11 21:12:04 · 175 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题51_数组中的逆序对
题目描述在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出,即输出P%1000000007。思路将数组中分为两个数组,分别为左数组与右数组。如果可以统计出左数组的逆序数leftCount和右数组的逆序数rightCount。那么如果可以再统计出逆序对的两个数字分别在左右数组...原创 2019-03-11 20:35:37 · 195 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题8_二叉树的下一个节点
题目描述 给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左、右孩子节点的指针,还有一个指向父节点的指针。 思路 若该结点有右孩子结点,那么中序遍历中的下一个结点就是其右子树最左边的结点; 若该结点没有右孩子结点 若该结点是其父结点的左孩子,那么中序遍历中的下一个结点就是其父结点; 若该结点...原创 2019-03-11 18:30:33 · 218 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题38_字符串的排列
题目描述 输入一个字符串,打印出该字符串中字符的所有排列。 思路 一个字符串可以分成两部分看,一部分是第1个字符,另一个部分是后面所有的字符。先固定第1个字符,然后将后面所有字符的所有排列与第1个字符组合。之后再将其他位置的字符与第1个字符交换,然后再将后面所有字符的所有排列与第1个字符组合。 C++实现 class Solution {public: ve...原创 2019-03-15 00:01:29 · 187 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题17_打印1到最大的n位数
题目描述 输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数999。 思路 方法一由于可能会有溢出,因此需要使用字符串来模拟整数加法,因此需要实现一个对整数字符串加1的函数。方法二将该问题看做是0~9十个字符的全排列问题,然后用递归的方式实现。 C++实现 方法一void Increment(string&...原创 2019-03-14 20:09:29 · 199 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题14_剪绳子
题目描述 给你一根长度为n的绳子,请把绳子剪成m段(m、n都是整数),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]*k[1]*...*k[m]可能的最大乘积是多少。(绳子只能在整数的位置剪) 思路 设f(i)表示长度为i的绳子的可能最大乘积,那么f(n)=max{f(i)*f(n-i)},i=1,2,…,n。 C++实现 int maxProduc...原创 2019-03-14 17:15:56 · 214 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题47_礼物的最大价值
题目描述 在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或向下移动一格,直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物? 思路 动态规划。设函数f(i,j)表示到达坐标(i,j)的格子时能拿到的礼物总和的最大值,那么到达(i,j)只能通过格子(i-1,j)或者(...原创 2019-03-14 12:25:09 · 181 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题42_连续子数组的最大和
题目描述 输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。 思路 动态规划。设表示以第个数字结尾的子数组的最大和,那么我们需要求出,其中。那么递推公式为:直观理解就是,如果以第i-1个数字结尾的子数组的最大和小于等于0,那么以第i个数字结尾的子数组的最大和就是第i个数;相反,如果第i-1...原创 2019-02-12 20:39:49 · 262 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题36_二叉搜索树与双向链表
题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。 思路 分治。 C++实现 class Solution {public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree==NULL)retu...原创 2019-02-12 19:50:46 · 248 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题57(一)_和为s的数字
题目描述 输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。 思路 使用两个游标分别指向数组的首位,首尾元素的和作为当前的和。如果该和大于s,将尾部的游标减一;如果该和小于s,将首部的游标加一。 C++实现 class Solution {public: vector<int&g...原创 2019-03-11 22:43:36 · 184 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题57(二)_和为s的连续正数序列
题目描述 输入一个正数是,打印出所有和为s的连续正数序列。 思路 初始时,使用低、高两个游标分别指向1和2;如果两个游标的和大于s,那么右移低游标,如果两个游标的和小于s,那么右移高游标。如何恰好等于s,将序列加入的结果中,并右移低游标,开始寻找新的满足需求的序列。 C++实现 class Solution {public: vector<vector...原创 2019-03-11 22:56:30 · 240 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题50(二)_字符流中第一个只出现一次的字符
题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。 思路 一个字符占8位,故字符不会超过256个,所以用一个大小为256的数组记录每个字符的出现次数。然后依次扫描原始字符串中的字符,遇到第1个出现次数为1的字符...原创 2019-03-13 18:57:33 · 449 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题41_数据流中的中位数
题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。 思路 维护一个最大堆和一个最小堆,其中最大堆中的所有数均小于最大堆中的数。并其维持两个堆...原创 2019-03-13 16:37:38 · 222 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题45_把数组排成最小的数
题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如,输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323. 思路 贪心。假设数组中只有两个数字m和n,那么我们只需要比较mn和nm。如果mn<nm,则打印出mn,也就是m应该排在n前面;否则打印nm,n排在m前面;这样我们就定义了一种比较规则,可以...原创 2019-03-13 15:14:36 · 208 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题50(一)_第一个只出现一次的字符
题目描述 在字符串中找出第一个只出现一次的字符。如输入”abaccdeff”,则输出’b’。 思路 使用hash表统计各个字符的出现次数。然后从头扫描字符串,当遇到第一个只出现一次的字符,则返回。 C++实现 class Solution {public: int FirstNotRepeatingChar(string str) { uno...原创 2019-03-13 02:17:28 · 158 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题18(二)_删除链表中重复的节点
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。 思路 递归。先判断队首元素是否重复,如果重复的话,将重复的元素全部删除,然后递归的调用删除之后节点中的重复元素。 C++实现 class...原创 2019-03-13 02:07:45 · 183 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题18(一)_删除链表的节点
题目描述 给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该结点。 思路 为了在O(1)时间内实现删除节点,那么可以将该节点后一个节点的值拷贝到该结点,然后直接删除该节点的后一个节点即可。 C++实现 void deleteNode(ListNode* node){ if(node==NULL)return; Lis...原创 2019-03-13 01:36:15 · 204 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题10_斐波那契数列_跳台阶
一、斐波那契数列 题目描述 写一个函数,输入n,求斐波那契数列的第n项。其中斐波那契数列的定义如下: 思路 显然,斐波那契数列已经给出了递推的方程。通常,有了递推方程后,那么即可以用分治,也可以用动态规划。假设,我们要计算f(5)=f(4)+f(3)=f(3)+f(2)+f(3)=…,显然在计算f(5)的是否要重复的计算两次f(3)。所以如果用分治的话,就会有很多重复计...原创 2019-03-13 01:17:20 · 239 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题6_从尾到头打印链表
题目描述 输入一个链表的头结点,从尾到头反过来打印出每个节点的值。 思路 递归。 C++实现 class Solution {public: vector<int> res; vector<int> printListFromTailToHead(ListNode* head) { if(head==NULL)...原创 2019-03-13 00:54:13 · 244 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题59_队列的最大值
题目描述 给定一个数组num和滑动窗口的大小size,请找出所有滑动窗口里的最大值。 思路 我们用一个双向队列来模拟滑动窗口,但是我们并不把所有窗口中的数字都保存在双向队列里,而是只保留那些可能是最大值的数字。在初始往双向队列中插入数字时,先插入第1个数字。当插入第2个数字时,如果大于第1个数字,那么第1个数字就不可能成为滑动窗口的最大值,因此将第1个数字弹出。如果小于第1个...原创 2019-03-13 00:46:55 · 353 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题58(二)_左旋转字符串
题目描述 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。比如,输入字符串”abcdefg”和数字2,该函数将返回左旋转两位得到的结果”cdefgab”。 思路 假设给定一个长度为n的矩阵,然左旋转k个字符。先反转整个句子,然后旋转右边的k个和左边的n-k个字符。 C++实现 class Solution {public: string Le...原创 2019-03-12 22:39:57 · 320 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题58(一)_翻转字符串
题目描述 输入一个英文,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样的处理。例如输入字符串“I am a student.”,则输出“student. a am I”。 思路 方法一先翻转整个句子,再翻转句子内的单词。例如先翻转整个句子“.tneduts a ma I”,反翻转内部的逐个单词“student. a ma I”。方法二...原创 2019-03-12 22:18:03 · 305 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题49_丑数
题目描述 我们把只包含因子2、3和5的数称作丑数。求按小到大的顺序的第1500个丑数。习惯上我们把1当作第一个丑数。 思路 我们希望创建一个丑数的数组,数组里是排好序的丑数。由于丑数的定义,那么每个丑数均是前面丑数乘以2、3或者5得到的。为了获得下一个丑数,我们希望能够获得三个丑数记为t2,t3和t5。其中t2表示该丑数乘以2刚好大于当前丑数,而t2之前的丑数乘以2小于当前的丑数...原创 2019-03-16 12:26:08 · 235 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题40_最小的k个数
题目描述 输入n个整数,找出其中最小的k个数。 思路 方法一可以利用快排的Partition方法,找到第k个数,其左边的所有数及该数就是我们要找的数。时间复杂度为O(n),但是需要修改数组。方法二维持一个大小为k的大根堆,目标是在遍历完整个数组后堆中的数就是最小的k个数。首先,先将前k个数装入到大根堆中,之后新来的数与根相比。如果小于根,则将根弹出,并将这个数插入堆中。...原创 2019-02-12 01:13:04 · 229 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题39_数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 思路 方法一 数组中如果有一个数字出现的次数超过了数组长度的一半。如果对这个数组进行排序,那么这个数字一定是中位数。这里可以使用基于快排的Partition函数在O(n)的时间复杂度内找出中位数。 使用Partition可以将指定数字放到排序后应该在的位置,如果这个数是中位数,那么只需要再统计一下这个...原创 2019-02-11 23:46:47 · 221 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题32_二叉树的层次遍历
题目描述 问题一:从上往下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。 问题二:从上往下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。 问题三:按照“之”字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。 思路 对于问题一,只需要使用一个队列,依次将每层的节点放...原创 2019-02-11 00:06:45 · 310 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题16_数值的整数次方
#include <cfloat>class Solution {public: double Power(double base, int exponent) { //0的负数次方直接返回 if(equal(base,0.0)&&exponent<0)return 0.0; unsigned i...原创 2018-11-01 21:09:28 · 514 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题15_二进制中1的个数
1.解法1 int NumberOf1(int n){ int count = 0; unsigned int flag = 1; while(flag){//当flag中的1移到越界后,flag值会转变为0 //当n&flag不为0时,表示当前flag中1对应的位置不为0 ...原创 2018-11-01 18:28:53 · 499 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题13_机器人的运动范围
一、题目描述 地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7=18。但它不能进入方格(35,38),因为3+5+3+8=19。请问该机器人能够到达多少个格子? 二、思路 ...原创 2018-11-01 14:27:34 · 548 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题12_矩阵中的路径
一、题目描述 设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再进入该格子。 二、思路 典型的回溯题。在回归的过程中需要全局变量来记录当前的访问状态,已经字符串已经匹配的长度。 三、C++实现...原创 2018-11-01 13:25:19 · 514 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题9_用两个栈实现队列
一、题目描述 用两个栈实现一个队列。 二、思路 维护两个栈,一个“入栈”和一个“出栈”。如果要向队列中加入元素,那么就将这个元素压入的“入栈”中;如果队列要删除一个,那么就从“出栈”中弹出一个元素,如果“出栈”中没有元素,那么将“入栈”的所有元素都倒入到“出栈”中,再将“出栈”的栈顶元素弹出。 三、C++实现 class MyQ...原创 2018-10-28 01:12:35 · 525 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题7_重建二叉树
一、前序遍历与中序遍历重建二叉树 1.题目描述 输入一颗二叉树的前序遍历序列和中序遍历序列,请根据这两个序列重建一棵二叉树。(假设输入的前序遍历和中序遍历的结果都不包含重复的数字) 2.思路 前序遍历的第一个数就是二叉树的根结点,这个根结点通常是在中序遍历的中间位置。在中序遍历中,根结点左边的数都在二叉树的左子树中,右边的数都在二叉树的右子树中。...原创 2018-10-27 20:00:29 · 545 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题11_旋转数组的最小数字
class Solution {public: int minNumberInRotateArray(vector<int> rotateArray) { int size = rotateArray.size(); int low=0,high = size-1; int mid = -1; while(...原创 2018-10-29 13:12:47 · 508 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题5_替换空格
题目描述 请实现一个函数,把字符串中的每个空格替换成“%20”。例如,输入“We are happy.”,则输出“We%20are%20happy.”。 思路 如果从前往后替换,每次替换都需要移动空格后的所有元素。不妨,先统计空格数,确定了替换后字符串应该有多长,然后从后往前进行替换。 C++实现 /*****************...原创 2018-09-03 12:14:53 · 886 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题4_二维数组中的查找
题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数? 思路 对于二维数组,搜索的起点可能有四个位置,分布对应矩形的四个角。对于左上角来说,当前位置为最小值,如果要搜索的数大于该值,那么搜索方向可以是右边、也可以是下边,也就是说...原创 2018-09-03 11:10:35 · 873 阅读 · 0 评论 -
《剑指offer》学习笔记_面试题26_树的子结构
问题描述输入两棵二叉树A和B,判断B是不是A的子结构。思路先搜索A找到与B的根节点值相同的节点,设为C;然后判断B是否是C的子树,如果不是就继续搜索A,找到下一个与B的根结点值相同的结点(NULL是子树但并不是子结构)。C++实现class Solution {public: bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoo...原创 2019-01-13 23:29:44 · 267 阅读 · 0 评论