
剑指offer
我是黄大仙
黄大仙
展开
-
用两个栈实现队列
题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 栈是先进后出,压入顺序为abc,出栈顺序为cba,压入的顺序和出栈的顺序相反,因此只需要出栈两次,便可 以使得出栈的顺序和压入的顺序一样。两个栈A和B,A负责压入,每次输出的时候,便将A中的数据出栈到B中 然后B再出栈,便能够实现队列的功能。 public class Solution {原创 2015-12-28 11:50:03 · 379 阅读 · 0 评论 -
二叉树的镜像
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像。 乍一看不知从何下手,但是仔细分析,二叉树的镜像,其实就是将左右子树交换,利用一个递归就可以实现了。 public class Solution { public void Mirror(TreeNode root) { if(root==null){ return;原创 2016-02-11 11:09:27 · 172 阅读 · 0 评论 -
顺时针打印矩阵
题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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. 将矩阵看成是一个一个的圈,开始打印最外层圈,然后打印次外层圈,一直打印完。接着讨论如何打印圈,先打 印横排,然后打印右原创 2016-02-13 14:43:19 · 233 阅读 · 0 评论 -
包含min函数的栈
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。要求在O(1)的时间内得到最小元 素。 可以用两个栈来实现这个功能,栈s1和s2,s2保留s1当中的最小元素,当s1入栈时,s2要考虑新入栈的元素是 否比之前的最小元素小,如果小则s2入栈新元素,如果大,则s2入栈之前的最小元素。当s1出栈时,s2也一同 出栈。 public class Soluti原创 2016-02-13 18:34:01 · 209 阅读 · 0 评论 -
栈的压入、弹出序列
题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。思路:建立一个辅助栈,依次将压入序列压入栈内,并且判断当前栈顶元素是否等于弹出序列的元素,如果等于则将元素弹出,并将弹出序列的指原创 2016-05-02 13:49:04 · 391 阅读 · 0 评论 -
从上往下打印二叉树
题目描述从上往下打印出二叉树的每个节点,同层节点从左至右打印。思路:用队列保存将要打印的节点,出队列时,将左节点和右节点分别加入队列当中,直到队列为空,打印完毕。 public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { if(root==null){ return null;原创 2016-05-02 14:42:20 · 206 阅读 · 0 评论 -
从尾到头打印链表
题目描述输入一个链表,从尾到头打印链表每个节点的值。 思路:有两种解决方法,第一种,采用栈的方式,遍历链表,并将链表依次入栈,然后再出栈打印;第二种,递归。第一种方法栈public void printListFromTailToHead(ListNode listNode) { Stack<Integer> stack=new Stack<Integer>(); whi原创 2016-05-02 14:56:22 · 226 阅读 · 0 评论 -
重建二叉树
题目描述输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。思路:根据前序遍历和中序遍历的特点,以题目当中的输入为例,1为根节点,再到中序遍历当中找根节点,找到之后左边为左子树4、7、2,右边为右子树5、3、8、6,再原创 2016-05-02 19:05:53 · 223 阅读 · 0 评论 -
二叉搜索树的后序遍历序列
题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。例如输入{5,7,6,9,11,10,8}则输出true。思路:二叉搜索树的特点是左子树的所有节点比根节点小,右子树的所有节点比根节点大,后续遍历最后一个节点是根节点,以题目中的输入为例,8为根节点,5、7、6均比8小,为左子树,9、11、10均比8大,为原创 2016-05-02 19:52:22 · 224 阅读 · 0 评论 -
二叉树中和为某一值的路径
题目描述输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 输入如图所示的一颗树,目标值为22,则输出【10,12】和【10,5,7】 思路:前序遍历整棵树,当路径上节点的和等于目标值时,将这条路径保存,然后继续遍历,直到节点为空返回。public ArrayList<ArrayList<Integer>>原创 2016-05-03 11:09:47 · 203 阅读 · 0 评论 -
复杂链表的复制
题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向链表中任意一个节点)。链表的数据结构为public class RandomListNode { public int label; public RandomListNode next = null; public RandomListNode random = null;原创 2016-05-04 15:55:44 · 230 阅读 · 0 评论 -
链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点。 可以用两个指针实现,first和second均指向头指针,将second指针后移动k-1位,然后再将两个指针同时往后 移动,直到second的next指向空。唯一需要注意的就是输入的k必须为正数,且不能超过链表的长度。 public class Solution { public ListNode FindKthToTa原创 2016-02-10 10:49:59 · 240 阅读 · 0 评论 -
合并两个排序的链表
题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 从链表头开始依次比较两个链表,然后从小到大依次串接起来,然后再返回链表头,即可完成。 public class Solution { public ListNode Merge(ListNode list1,ListNode list2) { if(lis原创 2016-02-11 09:51:53 · 219 阅读 · 0 评论 -
数的子结构
题目描述 输入两颗二叉树A,B,判断B是不是A的子结构。 采用两个递归来实现,第一个递归是遍历树A,找到A中与B的根节点相等的节点,第二个递归是用来比较从找到 的节点开始与B树每个节点进行比较,如果都相同则是子树,如果不相同,则继续进行寻找,如果没找到,则不 不是A的子树。 public class Solution { public boolean HasSubtre原创 2016-02-11 10:56:31 · 604 阅读 · 0 评论 -
跳台阶
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 假设青蛙跳上n级台阶有F(n)种跳法,那么当跳上第n级台阶之时,要么从第n-1级台阶跳1级跳上来,要么从第 n-2级台阶跳2级跳上来。因此F(n)=F(n-1)+F(n-2),很明显是一个斐波那契数列,因此很容易写出代码。 public int JumpFloor(int target)原创 2015-12-29 10:11:18 · 251 阅读 · 0 评论 -
变态跳台阶
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少 种跳法。 假设青蛙跳上n级台阶共有F(n)种跳法,则F(n)=F(n-1)+F(n-2)+F(n-3)+……+F(1)+1,而F(n-1)=F(n-2)+F(n-3) +……+F(1)+1,因此F(n)=2F(n-1) public int JumpFloorII(int t原创 2015-12-29 10:22:06 · 203 阅读 · 0 评论 -
矩形覆盖
题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩 形,总共有多少种方法? 同样也是一个斐波那契数列的应用,假设有F(n)种方法覆盖,那么当有F(n-1)种方法覆盖住之后,剩余只能用一 块小矩形竖着覆盖,当有F(n-2)种方法覆盖住之后,剩余的地方可以用两块小矩形横着放或者竖着放,但是如果 竖着放,则放置的方法包含在F(n原创 2015-12-29 10:35:50 · 239 阅读 · 0 评论 -
斐波那契数列
题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 所谓斐波那契数列就是F(n)=F(n-1)+F(n-2),当n=1或者n=2时,F(n)=1;因此很容易想到递归的方法 //采用递归的方法 public int FibonacciDiGui(int n){ if(n<=0){ return 0; }else if(n==1原创 2015-12-28 12:48:29 · 514 阅读 · 0 评论 -
从尾到头打印链表
题目描述 输入一个链表,从尾到头打印链表每个节点的值。 有两种方法可以解决这个问题,第一种将链表翻转,遍历一遍,然后将所有的指针翻转;第二种利用递归思想 如果next不为空,则继续往下递归,当next为空时,输出。 第一种方法 public ArrayList printListFromTailToHead(ListNode listNode) { ArrayLi原创 2015-12-25 15:27:23 · 335 阅读 · 0 评论 -
二维数组查找
题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请 完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 解题思路: 按照一般搜索二维数组的方法,从左到右,从上到下,比较难根据这个数组的特点进行快速搜索。可以从 右到左,从上到下,这样在查找的时候,跟每一个元素相关的行和列连接起来原创 2015-12-21 12:00:05 · 284 阅读 · 0 评论 -
二进制中1的个数
题目描述 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。 一个二进制数,减去1,最右边的1变成0,1后边的0全变成1。比如二进制1100,进去1变成1011。如果再和 原来的数进行与运算,则变成1000,即将末位的1变成0。如此循环知道数值变成0,即可知道二进制数当中包 含多少位1. public class Solution { public int原创 2016-02-08 12:38:30 · 253 阅读 · 0 评论 -
数值的整数次方
题目描述 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 很简单的题目,但是要考虑到程序的完整性,比如当exponent为负数和0的时候。 public double Power(double base, int exponent) { double result=1; if(expone原创 2016-02-08 16:13:21 · 261 阅读 · 0 评论 -
调整数组顺序使奇数位于偶数前面
题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶 数位于位于数组的后半部分。 可以用两个指针来指向数组,odd指向数组头,只往后移动;even指向数组尾,只往前移动。然后分别循环, 如果odd public class Solution { public void reOrderArray(int [] arra原创 2016-02-10 10:34:22 · 285 阅读 · 0 评论 -
反转链表
题目描述 输入一个链表,反转链表后,输出链表的所有元素。 可以设置三个指针,分别是pre,node,after,然后通过循环不断的反转指针,最终实现整个链表的反转。 public class Solution { public ListNode ReverseList(ListNode head) { if(head==null||head.next==n原创 2016-02-11 09:41:16 · 313 阅读 · 0 评论 -
数组中出现次数超过一半的数字
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。思路1:如果这个数组是有序的,那么处于数组中间的数字一定是我们要 找的数字,如果存在的话。因此可以用partition的方法对数组进行排序 每排完一次,判断这个数字是否处于中间,如原创 2016-08-02 22:06:06 · 298 阅读 · 0 评论