剑指offer学习
小象一只
刚开始学习图像处理知识
展开
-
22. 栈的压入、弹出序列
题目描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。解析如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。如果下一个弹出的数字不在栈顶,需要把压栈序列中还没有入栈的数字原创 2015-08-20 16:53:53 · 425 阅读 · 0 评论 -
21. 包含min函数的栈
题目描述定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。解析添加一个辅助栈,存放与数据栈中每个元素对应的当前栈中的最小值。 维护辅助栈: 1. 入栈:把新元素添加到数据栈,当新元素比之前的最小元素小时,把新元素添加到辅助栈中,否则,把之前的最小元素重复插入到辅助栈中。 2. 出栈:从数据栈弹出元素的同时,也要将辅助栈中,与该元素对应的最小值弹出辅助栈。实原创 2015-08-20 16:52:08 · 489 阅读 · 0 评论 -
5. 从尾到头打印链表
题目描述输入一个链表的头结点,从尾到头反过来打印出每个结点的值。解析逆序打印链表,我们遍历链表只能从头到尾,现在要求我们从尾到头。后进先出,可以想到用栈存储遍历的节点,然后打印出栈序列。 而递归的本质就是栈结构,在打印本节点之前,先打印本节点的下一个节点。实现void PrintListReversingly_Iteratively(ListNode* pHead){原创 2015-08-20 16:21:25 · 287 阅读 · 0 评论 -
3. 二维数组中的查找
参考:二分查找方法题目描述在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。解析方法一:剑指offer中提供的方法 如果我们从左上角开始查找,那么当查找元素比左上元素大时,无法判断是应该向下、向右还是向右下;从右下也是同理。 但是如果我们从右上角开始查原创 2015-08-20 16:18:39 · 358 阅读 · 0 评论 -
7. 用两个队列实现栈
题目描述用两个队列实现一个栈,完成栈的Push和Pop操作。 解析两个队列queue1和queue2 入栈:直接压入queue1 出栈:如果queue1不为空,将queue1中的元素除队尾元素外,其他全部弹出压入queue2中;否则,将queue2中的元素除队尾元素外,其他全面弹出压入queue1中。实现#include #include using namesp原创 2015-08-20 16:29:06 · 409 阅读 · 0 评论 -
20. 顺时针打印矩阵
题目描述输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.解析 打印第一圈的左上角坐标是(0,0),第二圈的的左上角坐标是(1,1),所以,每一圈的左上角坐标选定为原创 2015-08-20 16:49:19 · 325 阅读 · 0 评论 -
11. 数值的整数次方
题目实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。解析考虑base 和 exponent的取值分类。base和exponent可以是正数,负数,0。 (base,exponet): (0, 0):数学上没有意义,定义为0,可与面试官说明。 (0,负数):需要特殊处理原创 2015-08-20 16:33:59 · 318 阅读 · 0 评论 -
15. 链表中倒数第k个结点
题目描述输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表中有6个结点,从头结点开始它们的值依次是1,2,3,4,5,6.这个链表的倒数第3个结点是值为4的结点。解析假设整个链表有n个结点,那么倒数第k个结点就是从头结点开始的第n-k个结点.需要两次遍历链表,第一次统计链表的中的结点个数,第二次就能找到链表的原创 2015-08-20 16:40:12 · 374 阅读 · 0 评论 -
12. 打印1到最大的n位数
题目描述输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,打印出1,2,3一直到最大的3位数即999.解析n的取值范围可以很大,考虑大数问题。最常见的方法是用字符串或者数字表达大数。把问题转换成数字排列问题。在字符串上模拟数字加法思考: 如何用字符串存储数字; 如何在字符串表达的数字上模拟加法 把字符串表达是数字打印出来实现#inc原创 2015-08-20 16:35:27 · 312 阅读 · 0 评论 -
19. 二叉树的镜像
题目struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; };解析因为二叉树的存储结构是通过链表存储的。所以求二叉树的镜像,只需要修改每个结点的左右二叉树指针域原创 2015-08-20 16:48:19 · 423 阅读 · 0 评论 -
16. 反转链表
题目描述定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。struct ListNode{ int m_nValue; ListNode* m_pNext;};解析链表反转中,需要三个链表指针,一个指向当前被修改指针域的结点pNode,一个保存上一个结点pPrev,一个保存下一个需要被修改的结点pNext。实现Lis原创 2015-08-20 16:41:54 · 416 阅读 · 0 评论 -
13. 在O(1)时间删除链表结点
题目描述在给定单链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。链表结点与函数的定义如下:struct ListNode{ int m_nValue; ListNode* m_pNext;};void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted);解析在单链表中删原创 2015-08-20 16:36:57 · 364 阅读 · 0 评论 -
10. 二进制中1的个数
题目描述输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。解析方法一: 把n和1做与运算,判断n的最低位是不是1;接着把1左移一位得到2,再和n做运算,就能判断n的次低位是不是1……每次都能判断n的其中一位是不是1。这个解法的循环次数等于整数二进制的位数。 方法二: 把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制表示中有多少原创 2015-08-20 16:32:39 · 443 阅读 · 0 评论 -
9. 斐波那契数列
题目描述写一个函数,输入n,求斐波那契数列(Fibonacci)数列的第n项,斐波那契数列的定义为: 解析方法一:用递归的方法来求斐波那契数列 方法二:用循环来求斐波那契数列,用简单的方法从下往上计算,先计算根据f(0)、f(1)计算出f(2),在根据f(1)、f(2)计算出f(3)……依次计算到f(n)。时间复杂度为O(n)。实现//斐波那契数列递归方法long l原创 2015-08-20 16:31:28 · 889 阅读 · 0 评论 -
8. 旋转数组的最小数字
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 解析 1. 递增数组的旋转,例如,数组{1 2 3 4 5},经过旋转可以是{2 3 4 5 1},{3 4 5 1 2},{1 2 3 4 5},{原创 2015-07-19 15:07:41 · 322 阅读 · 0 评论 -
6. 重建二叉树
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。解析 根据先序遍历和中序遍历还原二叉树的主要思想: 1、先序遍历序列的第一个元素必定是根节点,可以由此获原创 2015-07-19 12:30:10 · 345 阅读 · 0 评论 -
24. 二叉搜索树的后序遍历序列
题目描述 输入一个整数数组,判断该整数数组是不是某二叉搜索树的后序遍历的结果,如果是则返回true,否则返回false。假设输入数组的任意两个数字都互不相同解析 在后序遍历得到的序列中,最后一个数字是树的根结点的值。数组中前面的数字可以分为两部分:第一部分是左子树结点的值,它们都比根结点的值小,第二部分是右子树结点的值,它们都比根结点的值大。主要代码实现bool V原创 2015-07-20 16:29:14 · 371 阅读 · 0 评论 -
38. 数字在排序数组中出现的次数
题目描述 统计一个数字在排序数组中出现的次数。例如,输入排序数组{1,2,3,3,3,3,4,5}和数字3, 由于3在这个数组中出现了4次,因此输出4.解析 1. 解法一: 该解法是最直观的解法,可以先使用二分查找先找到这个元素,然后分别向左和向右遍历,把左右相同的元素的个数都计算出来。 该方法很直观,当算法的效率太低。 2.解法二: 可以将原创 2015-07-20 16:33:15 · 340 阅读 · 0 评论 -
31. 连续子数组的最大和
题目描述 输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间负责度为O(n)。解析 1. 解法一: 看到这个题目,我们首先想到的是求出这个整型数组所有连续子数组的和,长度为n的数组一共有 n(n+2)/2个子数组,因此要求出这些连续子数组的和最快也需要O(n^2)的时间复杂度。但是题目要求的O(n)的时间复杂度,因此上述思路不原创 2015-07-24 16:23:25 · 449 阅读 · 0 评论 -
4. 替换空格(字符数组)
题目描述请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为”We Are Happy.“则经过替换之后的字符串为“We%20Are%20Happy.”解析直观的想法是,新建一个数组,逐个复制,遇到空格时,写入%20,但这需要占用额外空间。 如果我们顺序的遍历字符串,当遇到空格时,用%20替换空格,这将覆盖掉空格后面的字符 如果覆盖前,后移剩余字符串,那么移动的时原创 2015-08-20 16:23:13 · 447 阅读 · 0 评论 -
14. 调整数组顺序使奇数位于偶数前面
题目描述输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。解析注意代码的重用性构建。实现void ReorderOddEven_1(int *pData, unsigned int length){ //传参有效性判断 if (pData =原创 2015-08-20 16:37:47 · 309 阅读 · 0 评论 -
17. 合并两个排序的链表
题目描述输入两个递增排列的链表,合并这两个链表并新链表中的结点仍然是按照递增排列的。解析用递归的方法,修改链表的指针域。实现ListNode* Merge(ListNode* pHead1, ListNode* pHead2){ if (pHead1 == NULL) return pHead2; if (pHead2 == NULL原创 2015-08-20 16:43:49 · 397 阅读 · 0 评论 -
7. 用两个栈实现队列
题目描述用两个栈来实现一个队列,完成队列的Push和Pop操作。 解析两个栈stack1 和stack2 入队列:直接压入stack1即可 出队列:如果stack2不为空,把stack2中的栈顶元素直接弹出;否则,把stack1的所有元素全部弹出压入stack2中,再弹出stack2的栈顶元素实现#include #include using namespace s原创 2015-08-20 16:26:53 · 371 阅读 · 0 评论 -
18. 树的子结构
题目描述输入两颗二叉树A,B,判断B是不是A的子结构。struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; };解析递归调用HasSubtree遍历二叉树A,如原创 2015-08-20 16:44:58 · 345 阅读 · 0 评论