剑指offer
禾夕
这个作者很懒,什么都没留下…
展开
-
【剑指offer系列】 不用加减乘除做加法___47
题目描述: 写一个函数,求两个整数之和。要求不能使用加减乘除 分析: 既然题目要求不能用加减乘除,那么只能用到位操作了。 0和1 、1和0异或为1, 0和0 、1和1异或为0 0和0 、0和1 、1和0相与为0, 1和1相与为1 因此可以用异或做加法,与操作来计算进位 以3加5为例,3^5=6,3&5=1,则num=6,carr原创 2016-04-11 20:09:21 · 304 阅读 · 0 评论 -
【剑指offer系列】 丑数___34
题目描述: 我们把只包含因子2 、 3 、5的数称为丑数。 求按照从小到大的顺序输出第n个丑数,习惯上把1作为第一个丑数 分析: 1、我们可以通过遍历1到m个数,依次判断是否为丑数,直到找到第n个丑数 但是这种方法包含很多重复的判断,效率非常低 2、创建数组,依次保存已经找到的丑数。由于丑数都是由因子2、 3、 5生成的,因此可以方便的生成每原创 2016-04-10 19:42:01 · 313 阅读 · 0 评论 -
【剑指offer系列】 把数组排成最小的数___33
题目描述: 输入一个正整数数组,把数组中所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。 示例: 输入:{3 ,32 ,321} 输出:321323 分析: 首先把数组中的每个数字转换成字符串的形式,然后对所有字符串进行排序 排序的规则是:a+b static bool cmp(string& s1,strin原创 2016-04-10 19:25:42 · 305 阅读 · 0 评论 -
【剑指offer系列】 连续子数组的最大和___31
题目描述: 输入一个整型数组,里面有正数也有负数。 数组中一个或多个连续整数组成一个子数组。 求所有子数组的和的最大值 分析: 采用动态规划,f[i]表示以第i个数字结尾的子数组的最大和,因此所求结果应该为max(f[i]) 当遍历到第k个数时,以nums[k]结尾的子数组的最大和为max(f[k-1]+nums[k],nums[k])原创 2016-04-10 16:42:57 · 304 阅读 · 0 评论 -
【剑指offer系列】 最小的k个数___30
题目描述: 输入n个整数,返回其中最小的k个数 分析: 1)可以用快速排序的partion算法,当partion返回的索引为k或k-1时,左边的k个数恰好是最小的k个数(会改变原数组) 2)当输入的数据量非常大时,可用堆排序来解决。(适合海量数据) 代码: int partion(vector<int>& nums,int begin原创 2016-04-10 16:33:14 · 342 阅读 · 0 评论 -
【剑指offer系列】 数组中出现数字超过一半的数字___29
题目描述: 输入一个数组,找出其中出现次数超过一半的数字 分析: 1)首先可以想到利用快排的partion算法,对数组进行排序。 那么最后位于数组中间的那个数字一定是所求的结果。这种方法时间复杂度是O(nlgn) 2)采用计数法,时间复杂度只有O(n) 代码: int moreThanHalf(vector<原创 2016-04-10 15:31:03 · 284 阅读 · 0 评论 -
【剑指offer系列】 字符串排列___28
题目描述: 输入一个字符串,输入它的所有排列 示例: 输入:abc 输出:abc、acb、bac、bca、cab、cba 代码: void permutate(string &str,int start){ if(start==str.size()) cout<<str<<endl; for(int i=start;原创 2016-04-10 11:06:49 · 234 阅读 · 0 评论 -
【剑指offer系列】 二叉搜索树与双向链表___27
题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。左右孩子指针分别用于双向链表的prev、next指针 要求不能创建任何新的节点,只能调整树中节点指针的指向。 示例: 分析: 由于要求生成的双向链表是排好序的,因此可用中序遍历来遍历这个二叉搜索树。 可将二叉搜索树看成三部分:根节点、左、右子树,先分别将左、右原创 2016-04-10 10:31:48 · 305 阅读 · 0 评论 -
【剑指offer系列】 复杂链表的复制___26
题目描述: 请实现一个函数,实现复杂链表的复制。 在复杂链表中,每个节点除了有一个next指针指向下一个节点之外,还有一个sibling指针指向链表中的任意节点或者NULL 示例: 一个复杂链表的示例如下: 分析: 1)复制链表中的每一个节点,并用next指针链接 2)为每一个复制后的节点的sibling指针赋值,如A原创 2016-04-10 09:33:54 · 335 阅读 · 0 评论 -
【剑指offer系列】 第一个只出现一次的字符___35
题目描述: 输入一个字符串,找出其中第一个只出现一次的字符 示例: 输入:abacd 输出:b 分析: 首先遍历一次字符串,统计每个字符出现的次数 再次遍历字符串,找到第一个次数为1的字符 代码: char firstOnce(string& str){ int cnt[256]={0}; f原创 2016-04-10 19:50:41 · 293 阅读 · 0 评论 -
【剑指offer系列】 数组中逆序对___36
题目描述: 输入一个数组,求出其中逆序对的总个数 示例: 输入:{7, 5, 6, 4} ,逆序对有{7,6},{7,5},{7,4},{5,4},{6,4}几种情况 因此输出5 分析: 利用归并排序的思想进行排序,时间复杂度O(nlgn) 代码: int inversePairsCore(vector<int>&原创 2016-04-10 21:01:19 · 339 阅读 · 0 评论 -
【剑指offer系列】 两个链表的第一个公共节点___37
题目描述: 输入两个单链表,找出他们的第一个公共节点。若没有,则返回NULL 分析: 如果两个单链表有公共节点,那么在交点后的每一个节点都是公共的。因此两个单链表的构型必然是下图所示的Y型。 1)利用栈的先进后出,将两个链表的所有节点都入栈。然后再依次出栈。找出最后一个相同节点,即为第一个公共节点.但是这种方法需要两个栈作为辅助空间 2)首原创 2016-04-11 09:33:28 · 321 阅读 · 0 评论 -
【剑指offer系列】 圆圈中最后剩下的数字___45
题目描述: 把0 ,1 ,……, n-1这n个数排成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字。 求这个圆圈剩下的最后一个数字 示例: 输入:n=3,m=2,即把0 ,1 ,2这三个数字每次删除第二个,删除的依次为1, 0,剩下2 输出:2 分析: 经典解法,用环形链表模拟圆圈。当链表中只有一个节点时,退出。但是这原创 2016-04-11 19:57:10 · 1171 阅读 · 0 评论 -
【剑指offer系列】 n个骰子的点数___43
题目描述: 把n个骰子仍在地上,所有骰子朝上一面的点数之和为S。 输入n,输出S的所有可能值的出现概率 示例: 输入:n = 1 输出:S可能为1~6,每个出现的概率相等,均为0.166666 分析: 如果基于递归,可能会有很多重复的操作,因此采用循环来实现。 对于n个骰子,可能6^n种情况。首先统计每个值出现的次数,然后除原创 2016-04-11 15:13:04 · 427 阅读 · 0 评论 -
【剑指offer系列】 从1到n中1出现的次数___32
题目描述: 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数 示例: 输入12,则包含1的数字有1, 10 ,11 ,12,1共出现5次 输出5 分析: 1. 当从1开始向n遍历每个整数,对每个整数的每一位进行判断时,效率非常低。 2. 首先分析1346到21345中1出现的次数。可以分为两种情况: 1)高原创 2016-04-10 19:09:36 · 304 阅读 · 0 评论 -
【剑指offer系列】 翻转单词 VS 左旋字符串___42
题目描述: 输入一个英文句子,翻转句子中的单词的顺序 示例: 输入: “the sky is blue” 输出:”blue is sky the” 分析: 可以翻转整个句子,然后翻转其中的每个单词。 同时考虑去掉句子中多余的空格(句子首尾不能有空格,单词间只能有一个空格) (leetcode 151) 代码:原创 2016-04-11 14:44:55 · 365 阅读 · 0 评论 -
【剑指offer系列】 和为S的两个数字___41
题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使它们的和恰好为S。 如果有多对数字的和为S,输出其中任意一对即可 示例: 输入:{1 ,2 ,4 ,7 ,11}和9 输出:2he7 分析: 可以考虑从数组的两端向中间搜索的方式进行查找,这样时间复杂度为O(n) 代码: vector<int原创 2016-04-11 14:36:43 · 310 阅读 · 0 评论 -
【剑指offer系列】 数组中只出现一次的数字___40
题目描述: 一个数组中除了两个数字只出现了一次外,其它数字都出现了两次。找出这两个数 示例: 输入:{2 ,4 ,3 ,6 ,2 ,3} 输出:4,6 分析: 可以利用相同数字异或为0的思想进行查找 代码: bool isSet(int num,int bit){ return (num&(1<<bit))>原创 2016-04-11 10:30:05 · 309 阅读 · 0 评论 -
【剑指offer系列】 二叉树的深度___39
题目描述: 输入一棵二叉树,求其深度 。 树的深度定义为:从根节点到叶子节点的路径长度的最大值 示例: 分析: 对每个节点而言,以该节点为根节点的树的深度为左子树和右子树深度的较大值加1. 因此用递归可以很容易的实现 代码: int depth(treeNode *root){ if(root==NUL原创 2016-04-11 10:06:05 · 354 阅读 · 0 评论 -
【剑指offer系列】 数字在排序数组中出现的次数___38
题目描述: 统计一个数字在排序数组中出现的次数 示例: 输入:数组{1 ,2 ,3 ,3 ,3 ,3 ,4 ,5}和数字3 输出:4 分析: 数组的查找可以利用二分法的思想,分别在数组中找到数字第一次出现和最后一次出现的位置,则出现的次数为二者下标之差 。时间复杂度为O(nlgn). 代码: int getFirst(原创 2016-04-11 09:59:40 · 344 阅读 · 0 评论 -
【剑指offer系列】 二叉树中和为某一值的路径___25
题目描述: 输入一棵二叉树和一个整数,打印出二叉树中节点值之和为输入整数的所有路径 从树的根节点开始往下一直到叶节点所经过的所有节点形成一条路径 分析: 从根节点开始向下遍历,并用一个vector数组记录当前路径的所有节点值。 当遍历到叶子节点时,如果路径和恰好为目标值,则将这个数组加入到返回结果中。 然后继续遍历,直到遍历完所有路径。原创 2016-04-09 18:11:44 · 222 阅读 · 0 评论 -
【剑指offer系列】 二叉搜索树的后序遍历系列___24
题目描述: 输入一个整数序列,判断该序列是否是某二叉搜索树后序遍历的结果 示例: 输入{5,7,6},返回true 输入{5,6,7},返回false 分析: 后序遍历为:左、右、根,最后一个节点为根节点 比根节点小的都在左子树,比根节点大的都在右子树 然后分别对左右子树递归进行判断 代码: bool verif原创 2016-04-09 16:58:58 · 267 阅读 · 0 评论 -
【剑指offer系列】 从上往下打印二叉树___23
题目描述: 给定一棵二叉树的根节点,按照从上往下的顺序打印每一个节点,同一层的节点按照从左往右的顺序打印 示例: 分析: 遇到这中涉及到二叉树的层次问题的时候,利用队列这种数据结构可以使问题变得非常简单。 首先将根节点加入队列,然后从队列头部取出根节点。 如果节点的左右孩子非空,则依次将其加入到队列尾部。 最终所有节点原创 2016-04-09 15:47:53 · 266 阅读 · 0 评论 -
【剑指offer系列】 打印1到最大的n位数___12
题目描述: 输入数字n,顺序打印从1到最大的n位数 示例: 输入3,则打印1、 2 、3 …… 999 分析: 本题的陷阱就是n可能很大,用long long也会溢出。 因此要将数字转换成字符串表示,这样就不会溢出。 所以我们必须自己实现字符串的加法 代码: void add(string& str){ i原创 2016-04-07 15:13:38 · 196 阅读 · 0 评论 -
【剑指offer系列】 数值的整数次方___11
题目描述: 实现函数double power(double base,int exponent),求base的exponent次方。 不得使用库函数,不需要考虑大数问题 分析: 利用二分法的思想实现。 注意exponent时,base^exponent=(1/base)^(-exponent),如3^(-2)=(1/3)^2 代码:原创 2016-04-07 14:49:00 · 239 阅读 · 0 评论 -
【剑指offer系列】 二进制中1的个数___10
题目描述: 输入一个整数,输出该数二进制表示中1的个数。 示例: 输入9,9的二进制为1001,有2位为1,因此输出2 分析: 1)当一个整数n非0时,则一定至少有一位为1。 2)因此对于n-1,就是将n最右边的一个1变为0,将该位右边的所有位都变为1。如12的二进制为1100,12-1=11的二进制为1011,是将12最右边的1置为原创 2016-04-07 14:25:55 · 256 阅读 · 0 评论 -
【剑指offer系列】 斐波那契数列___9
题目描述: 输入n,求斐波那契数列的第n项。 斐波那契数列的递推公式: 示例: 输入2,f(2)=f(0)+f(1) = 1. 输出1 分析: 如果从n开始向下递归计算的话,根据递归树可以发现会有大量重复的计算。 因此我们从下向上迭代,直到得到第n项的值为止。 代码: long lon原创 2016-04-07 11:07:18 · 335 阅读 · 0 评论 -
【剑指offer系列】 旋转元素的最小数字___8
题目描述: 给定一个递增数组旋转后的数组,找出旋转数组中的最小值 示例: 旋转数组为{3,4,5 ,6, 7, 1 ,2},则输出为1 分析: 数组可能存在以下三种情况 利用二分法的思想,记录待查找的边界下标分别为left和right,此例中为0和6 1)如果nums[lef]int findMin(vector<int>&原创 2016-04-07 10:42:31 · 244 阅读 · 0 评论 -
【剑指offer系列】 替换空格___4
题目描述: 实现一个函数,把字符串中的每个空格替换成%20, 示例: 输入:“We are happy” 输出:“We%20are%20happy” 分析: 1)先正向遍历字符串,统计字符串中空格的长度,得到替换后的字符串长度 2)反向填充字符串,遇到空格时,则反向填充%20 时间复杂度为O(n) 代码: void replace(c原创 2016-04-06 14:48:24 · 244 阅读 · 0 评论 -
【剑指offer系列】 重建二叉树___6
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,重建该二叉树。 不考虑前序遍历序列和中序遍历序列长度不相等的情况,不考虑重复的数字 二叉树树节点定义如下:typedef struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x原创 2016-04-06 16:50:42 · 260 阅读 · 0 评论 -
【剑指offer系列】 从尾到头打印链表___5
题目描述: 给定一个链表的头节点,从链表尾部反向打印链表每个节点 节点定义如下: typedef struct listNode{ int val; struct listNode *next; listNode(int num):val(num),next(NULL){}}listNode; 分析: 对于一个单链表,我们可以将其看作一棵只有右孩子节点原创 2016-04-06 15:08:37 · 192 阅读 · 0 评论 -
【剑指offer系列】 在O(1)时间删除链表节点___13
题目描述: 给定一个单链表的头节点指针和一个节点指针,在O(1)时间删除该节点 分析: 要删除单链表的一个节点,正常的操作应是找到待删除节点的前驱节点,然后prev-next=toDel->next,再删除该节点 但是本题时间复杂度要求是O(1),因此不能遍历链表去找到目标节点的前驱。只能考虑将next节点的值赋给该节点,然后删除next节点。但是如果原创 2016-04-07 15:36:07 · 255 阅读 · 0 评论 -
【剑指offer系列】 调整数组顺序使奇数位于偶数前面___14
题目描述: 输入一个整数数组,实现一个函数来调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分 分析: 单纯的只实现这道题目很简单,只需要分别从数组前后向中间遍历,遇到不合要求时就交换即可。 但是我们可以扩展这个题目,将数组顺序的调整条件变为其它任意功能。如将能被3整除的放在前半部分等。 这样我们可以将判断条件换为一个函数,每原创 2016-04-07 16:07:29 · 260 阅读 · 0 评论 -
【剑指offer系列】 链表中倒数第k个节点___15
题目描述: 给定一个单链表的头节点,删除该链表的倒数第k个节点。(尾部节点为倒数第一个节点) 示例: 链表为:4–>3–>2–>1–>NULL,则倒数第一个节点为1,若k=3。 则输出值为3的那个节点的指针 分析: 对于单链表的这种查找问题,一般都可以用快慢指针来解决。 注意k <= 0和k > list.len两种情况返回NULL原创 2016-04-08 10:15:42 · 370 阅读 · 0 评论 -
【剑指offer系列】 栈的压入和弹出序列___22
题目描述: 输入两个整数序列,第一个为入栈序列,判断第二个是否为出栈序列 分析: 将入栈序列中的元素依次入栈,若出栈序列的元素为栈顶元素,则可以将该元素出栈。最后判断栈是否为空。 代码: bool isValid(vector<int>& in,vector<int>& out){ stack<int> stk; in原创 2016-04-08 16:58:03 · 369 阅读 · 0 评论 -
【剑指offer系列】 栈和队列___7
题目描述: 用两个栈实现一个队列 队列的声明如下:template<typename T> class Queue{public: void appendTail(const T& node); T deleteHead();private: stack<T> stack1; stack<T> stack2; 实现它的两个函数appendT原创 2016-04-06 21:59:30 · 336 阅读 · 0 评论 -
【剑指offer系列】 包含min函数的栈___21
题目描述: 定义栈的数据结构,请在该类型中实现一个能够获取当前栈中最小元素的min函数。 要求min、push、pop操作的时间复杂度都是O(1) 分析: 可以用两个栈来实现,其中一个栈存储所有压入的元素,另一个栈存储当前所有元素中的最小值。 两个栈的元素个数始终相同 代码: class Stack {public:原创 2016-04-08 16:54:15 · 355 阅读 · 0 评论 -
【剑指offer系列】 顺时针打印矩阵___20
题目描述: 输入一个矩阵,按照从外到里的顺序顺时针打印每个值 示例: 分析: 对于每一圈,可能存在以下几种情况 因此对每个方向的打印都要先进行条件判断,判断是否需要打印这个方向 代码: void printCircle(vector<vector<int> >&nums,int m,int原创 2016-04-08 16:41:48 · 346 阅读 · 0 评论 -
【剑指offer系列】 二叉树的镜像___19
题目描述: 输入一个二叉树 ,实现一个函数将二叉树转化为它的镜像 示例: 分析: 从根节点开始,交换它的左右孩子节点,一直向下递归。 如首先交换根节点8的左右孩子节点,然后交换节点6的左右孩子,再交换节点10的左右孩子即可。 代码: void mirrorTree(treeNode *root){原创 2016-04-08 15:43:43 · 281 阅读 · 0 评论 -
【剑指offer系列】 树的子结构___18
题目描述: 输入两棵二叉树A和B,判断B是不是A的子结构 示例: 下图中A有一部分子树和B是相同的,因此B是A的子结构 分析: 基本思想是首先在A中找到和B根节点值相同的节点,然后以此作为根节点分别递归判断左右子树和B是否相同。 代码: bool hasSubTree(treeNode *root1,tree原创 2016-04-08 15:34:04 · 258 阅读 · 0 评论