剑指Offer
个人刷《剑指Offer》的思路以及代码。
RojerAlone
脚踏实地,笨鸟先飞。
展开
-
剑指Offer系列-面试题57:删除链表中重复的结点
题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5思路:首先创建一个头结点,为了防止第一个结点就是重复结点。然后遍历整个链表,每一次while循环,都pass掉和当前结点值相同的结点,如本例中,在遍历到3的时候,遍历完一次,tmp指向了4,然后进入下一次循环,这次循环原创 2017-03-22 20:48:48 · 1247 阅读 · 0 评论 -
剑指Offer系列-面试题3:二维数组中的查找
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该参数。#include #include using namespace std;bool _find(int a[][4], int rows, int columns, int num){ bool r原创 2016-12-22 16:42:18 · 265 阅读 · 0 评论 -
剑指Offer系列-面试题4:替换空格
题目:请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy.”,则输出“We%20are%20happy.”。#include using namespace std;void replaceBlank(char str[], int length){ if(str == NULL || length <= 0) ret原创 2016-12-22 17:17:39 · 288 阅读 · 0 评论 -
剑指Offer系列-面试题5:从尾到头打印链表
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。#include #include using namespace std;struct ListNode{ int key; ListNode* next;};ListNode* createList(int n){ ListNode* pHead = new ListNode();原创 2016-12-22 17:59:11 · 272 阅读 · 0 评论 -
剑指Offer系列-面试题6:重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出二叉树并输出它的头结点。代码没有重新写,是15年秋数据结构的OJ题,徒手写的队列和二叉树的类。#include using namespace std;/*原创 2016-12-23 21:03:34 · 371 阅读 · 0 评论 -
剑指Offer系列-面试题7:用两个栈实现队列
题目:用两个栈实现队列,队列有两个函数,appendTail和deleteHead,分别完成在队尾添加数据和出队头。#include #include #include using namespace std;templateclass CQueue{public: CQueue() {} ~CQueue() {} void appendTail(c原创 2016-12-23 22:03:45 · 368 阅读 · 0 评论 -
剑指Offer系列-面试题8:旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.思考:最小值只有一个,只需要把数组遍历一遍就可以知道最小值,但是这种方法的复杂度为O(1),没有利用旋转数组的特性,达不到面试官的要求。旋转数组实际上可以划分为两个排序的子数组,而原创 2017-02-03 15:05:38 · 324 阅读 · 0 评论 -
剑指Offer系列-面试题9:斐波那契数列
题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。效率很低的解法(递归实现):long long Fibonacci(unsigned int n){ if(n <= 0) return 0; if(n == 1) return 1; return Fibonacci(n - 1) + Fibonacci(n -原创 2017-02-03 16:22:02 · 376 阅读 · 0 评论 -
剑指Offer系列-面试题10:二进制中1的个数
题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制数是1001,有2位是1.因此如果输入9,该函数输出2。原创 2017-02-04 15:02:41 · 377 阅读 · 0 评论 -
剑指Offer系列-面试题11:数值的整数次方
题目:实现函数double Power(double base, int exponent)。求base的exponent次方,不得使用库函数,同时不需要考虑大数问题。#include using namespace std;bool g_InvalidInput = false; /// 输入是否非法的标识/// 判断两个double类型的数是否相等bool equals(d原创 2017-02-04 18:00:07 · 268 阅读 · 0 评论 -
剑指Offer系列-面试题12:打印1到最大的n位数
题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的三位数即999。PS:代码没看懂#include #include "string.h"using namespace std;void PrintNumber(char *number){ bool isBeginning0 = true; int lengt原创 2017-02-07 15:10:38 · 285 阅读 · 0 评论 -
剑指Offer系列-面试题13:在O(1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,指定一个函数在O(1)时间删除该结点。链表结点与函数的定义如下:struct ListNode{ int m_nValue; ListNode* m_pNext;};void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted);代码:void DeleteNo原创 2017-02-07 15:22:52 · 254 阅读 · 0 评论 -
剑指Offer系列-面试题14:调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。void reOrderArray(vector &array){ if(array.size() <= 0) { return; } int head = 0; int tail = array.size() -原创 2017-02-14 22:04:09 · 357 阅读 · 0 评论 -
剑指Offer系列-面试题15:链表中倒数第K个结点
题目:输入一个链表,输出该链表中倒数第K个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始他们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。链表结点定义如下:struct ListNode { int m_nValue; ListNode* m_pNext; };原创 2017-02-15 14:09:41 · 280 阅读 · 0 评论 -
剑指Offer系列-面试题16:反转链表
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出翻转后链表的头结点。链表结点定义如下:struct ListNode{ int value; ListNode *pNext;};思路:创建3个指针,分别指向连着的3个结点。步骤:1、将中间结点的pNext指向第一个结点,然后第一个结点指向第二个结点,第二个结点指向第三个结点,第三个结点指向它的后一个结点;原创 2017-02-15 16:41:15 · 344 阅读 · 0 评论 -
剑指Offer系列-面试题17:合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。链表结点定义如下:struct ListNode{ int value; ListNode *pNext;};思路:注意鲁棒性。代码:ListNode* Merge(ListNode* pHead1, ListNode* pHead2){ if(pHead1 == NULL原创 2017-02-15 18:29:10 · 308 阅读 · 0 评论 -
剑指Offer系列-面试题18:树的子结构
题目:输入两颗二叉树A和B,判断B是不是A的子结构。二叉树结点的定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;};思路:代码:bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, Bi原创 2017-02-16 16:30:47 · 284 阅读 · 0 评论 -
剑指Offer系列-面试题19:二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。二叉树的结点定义如下:struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight;};思路:代码:// 递归实现void MirrorRecursively(BinaryTreeNode原创 2017-02-16 22:34:01 · 296 阅读 · 0 评论 -
剑指Offer系列-面试题20:顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵:1 2 3 45 6 7 89 10 11 1213 14 15 16则依次打印出数字1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10。思路:代码:void PrintMatrixClockwisel原创 2017-02-21 22:02:27 · 310 阅读 · 0 评论 -
剑指Offer系列-面试题21:包含min函数的栈
题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数,在该栈中,调用min、push及pop的时间复杂度都是O(1)。思路:建立一个新的栈minStack,每次push的时候,和minStack中的栈顶元素进行比较,如果比栈顶元素小,就入栈,minStack中栈顶元素一直是最小的数。如果pop,如果pop大小和minStack中的栈顶元素大小相同,就也将minStack原创 2017-02-22 22:09:44 · 410 阅读 · 0 评论 -
剑指Offer系列-面试题22:栈的压入、弹出序列
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出序列。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。思路:代码:bool IsPopOrder(vector pushV,vector popV){ boo原创 2017-02-22 22:53:26 · 341 阅读 · 0 评论 -
剑指Offer系列-面试题23:从上到下打印二叉树
题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。二叉树结点的定义如下:struct TreeNode{ int val; struct TreeNode *left; struct TreeNode *right;};思路:二叉树的层序遍历,用队列实现即可。代码:vector PrintFromTopToBottom(TreeNod原创 2017-02-23 15:03:11 · 255 阅读 · 0 评论 -
剑指Offer系列-面试题24:二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。思路:代码:/// 非递归bool VerifySquenceOfBST(vector sequence){ int size = sequence.size(); if(0 == size) retur原创 2017-02-23 16:20:27 · 296 阅读 · 0 评论 -
剑指Offer系列-面试题25:二叉树中和为某一值的路径
题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。思路:代码:struct TreeNode{ int val; struct TreeNode *left; struct TreeNode *right;};vector> result;vector tmp;原创 2017-02-27 21:02:08 · 348 阅读 · 0 评论 -
剑指Offer系列-面试题26:复杂链表的复制
题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。结点定义如下:struct ListNode{ int val; struct ListNode *next; struct ListNode *sibling;};思路:代码:ListNode* Clone(Lis原创 2017-02-27 22:09:31 · 333 阅读 · 0 评论 -
剑指Offer系列-面试题27:二叉搜索树与双向链表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路:由二叉搜索树的原理,中序遍历即为有序的链表,因此直接中序遍历,一边遍历,一边调整指针。代码:/// 非递归,中序遍历TreeNode* Convert(TreeNode* root){ if(root == NULL) { r原创 2017-03-12 20:55:21 · 392 阅读 · 0 评论 -
剑指Offer系列-面试题28:字符串的排列
题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。思路:代码:public ArrayList Permutation(String str) { ArrayList list = new ArrayList(); // 输入合法性判断原创 2017-03-12 21:51:46 · 330 阅读 · 0 评论 -
剑指Offer系列-面试题29:数组中出现次数超过一半的数字
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。思路:代码:/** * 返回数组中超过一半的数字,如果没有,返回0 * 定义两个变量,一个用来数组中某个数字的值,另一个count用来记录这个值出现的次数 * 由于超过一原创 2017-03-13 15:04:00 · 329 阅读 · 0 评论 -
剑指Offer系列-面试题30:最小的K个数
题目:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。思路:运用快排的思想,每次排序后,point点左边的数都小于point,因此只要让point的坐标等于k-1时,point以及它左边的数就是最小的k个数。但是这样会改变数组原有次序。另一种思路是事先设置一个大小为k的容器,同时设置一个变量max用来记录当前容器中最原创 2017-03-13 16:41:38 · 459 阅读 · 0 评论 -
剑指Offer系列-面试题31:连续子数组的最大和
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。思路:动态规划。代码:public boolean tag = false;public int FindGreatestSumOfSubArray(int[] array) { if(array == null || array.leng原创 2017-03-13 18:05:47 · 318 阅读 · 0 评论 -
剑指Offer系列-面试题32:从1到n整数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1、10、11和12,1一共出现了5次。思路:计算数字每一位出现1的次数,并相加,得到该数字中1出现的次数。参考这篇文章。代码:public int NumberOf1Between1AndN_Solution(int n) { int result = 0;原创 2017-03-13 21:22:45 · 398 阅读 · 0 评论 -
剑指Offer系列-面试题33:把数组排成最小的数
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。思路:通过比较两个数组合起来的数的大小,来进行排序,最后组合成为一个字符串即可。代码:public String PrintMinNumber(int[] numbers) { ArrayList li原创 2017-03-15 18:42:03 · 393 阅读 · 0 评论 -
剑指Offer系列-面试题34:丑数
题目:把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。思路:代码:public int GetUglyNumber_Solution(int index) { if (index <= 0) { return 0; } else if (index < 7原创 2017-03-15 19:55:15 · 492 阅读 · 0 评论 -
剑指Offer系列-面试题35:第一个只出现一次的字符
题目:在一个字符串(1思路:代码:public int FirstNotRepeatingChar(String str) { if (str == null || str.equals("")) { return -1; } char[] chars = str.toCharArray(); int[] a = new int['z' - 'A' +原创 2017-03-15 20:22:12 · 352 阅读 · 0 评论 -
剑指Offer系列-面试题37:两个链表的第一个公共结点
题目:输入两个链表,找出它们的第一个公共结点。思路:代码:public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pH原创 2017-03-15 21:40:27 · 303 阅读 · 0 评论 -
剑指Offer系列-面试题38:数字在排序数组中出现的次数
题目:统计一个数字在排序数组中出现的次数。思路:二分查找该数字第一次出现的位置,然后找最后一次出现的位置,相减即可。用二分查找,时间复杂度为O(log n)。代码:public int GetNumberOfK(int [] array , int k) { if (array == null || array.length <= 0) { return 0; } int s原创 2017-03-15 22:23:44 · 338 阅读 · 0 评论 -
剑指Offer系列-面试题39:二叉树的深度
题目:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。思路:递归。代码:public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.v原创 2017-03-16 18:13:25 · 284 阅读 · 0 评论 -
剑指Offer系列-面试题39-2:判断一棵树是否为平衡二叉树
题目:判断一棵树是否为平衡二叉树思路:根据上一题的二叉树的深度,在递归过程中加上标识符,递归到当前节点,判断当前子树是不是一个平衡二叉树,如果不是,就把标识符置为false,返回标识符即可。代码:private boolean result = true;public boolean IsBalanced_Solution(TreeNode root) { TreeDepth(r原创 2017-03-16 20:05:38 · 633 阅读 · 0 评论 -
剑指Offer系列-面试题40:数组中只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。思路:利用异或的特点,一个数的二进制异或自己,结果为0,既然数组中只有两个数字出现一次,其他出现两次,那么首先考虑这样一个问题:一个数组中,只有一个数字出现一次,其他数字出现两次,那么只需要全部异或,既然一个数异或自己为0,而0异或任何数都为这个数本原创 2017-03-16 21:08:28 · 541 阅读 · 0 评论 -
剑指Offer系列-面试题41:和为s的两个数字以及和为s的正数序列
题目一:输入一个递增排序的数组和一个数字,输出数组中任意一对和为s的数字。思路:代码:public ArrayList FindNumbersWithSum(int [] array,int sum) { ArrayList result = new ArrayList(); if (array == null || array.length < 2) { r原创 2017-03-16 22:06:57 · 598 阅读 · 0 评论