剑指Offer算法题JAVA版4-12题(全是个人写的非官方,只供参考和自己复习,测试用例都通过了)
来源:互联网 发布:晨兴资本 知乎 编辑:程序博客网 时间:2024/06/05 15:22
4.输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
(思路:用递归不断的将中序序列分成左右,两部分。)
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */public class Solution { public TreeNode reConstructBinaryTree(int [] pre,int [] in) { Solution s= new Solution(); TreeNode node=s.creatTree(pre,0,pre.length-1, in,0,in.length-1); return node; } public TreeNode creatTree(int[] per,int perStart,int perend,int[] in, int inStar,int inEnd){ if(perStart>perend||inStar>inEnd){//叶子节点左右孩子皆为Null return null; }else{ TreeNode node=new TreeNode(per[perStart]); int middle=-1; for(int i=inStar;i<=inEnd;i++){//当前节点,在中序遍历序列中的位置 if(in[i]==per[perStart]){ middle=i; } } node.left=creatTree(per,perStart+1,middle-inStar+perStart,in,inStar,middle-1); node.right=creatTree(per,middle-inStar+perStart+1,perend,in,middle+1,inEnd); return node; } }}
5.用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
(思路:第一个栈专门放入,第二个栈负责弹出,出栈的时候,如果第二个栈是空的,将第一个栈的所有内容弹出并放入第二个栈,之后从第二个栈弹出,如果第二个栈不为空,则直接弹出。)
import java.util.Stack;public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); public void push(int node) { stack1.push(node); } public int pop() { if(stack2.isEmpty()){ while(!stack1.isEmpty()){ stack2.push(stack1.pop()); }
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
/*考虑了出现,相同数字的情况的二分查找法,经测试,只要复合旋转规范,无论是否有重复数字都可通过,时间复杂度O(logn)*/public int minNumberInRotateArray(int [] array) { if(array==null){ return 0; }else{ int pre=0; int end=array.length-1; while(pre!=end){ if(array[pre]==array[end]){//这里处理出现相同数字的情况 pre++; end--; }else if(array[pre]<array[end]){ end=pre; }else if(array[pre]>array[end]){ ; double d=((double)(pre+end))/2; int middle=(int)Math.ceil(d); if(array[middle]>array[end]){ pre=middle; }else if(array[middle]<array[end]){ end=middle; }else if(array[middle]==array[end]&&middle==end){ pre=middle; }else if(array[middle]==array[end]&&middle!=end){//相同数字处理 end=middle; } } } return array[pre]; } }
7.大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。
(用递归完全行不通,运算时间爆炸,用动态规划完成,
public int Fibonacci(int n) { if(n==0){ return 0; }else if(n==1){ return 1; }else{ int b=0;//等价与F(n-2) int a=1;//等价与F(n-1) int f=0; for(int i=2;i<=n;i++){ f=a+b;//F(n)=F(n-1)+F(n-2) b=a;//下次循环F(n+1)=F(n)+F(n-1),故b=a,等价与令b等于当次循环的F(n-1),也就是下次循环的F(n-2)。 a=f;//同上,当次的F(n)是下次的F(n-1)a为下次的F(n-1) } return f; } }
8.一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
(思路这道题,关键在于问题的分析,如果你能很清楚的分析出这个一斐波那契数列问题,F(n)=F(n-1)+F(n-2),那做法,就如上题一样了,分析下思路,比如,青蛙想跳到第3层,那么它有两种选择,1。是从第一层跳两阶上来【连续跳两次不行,因为它跳到第二层的时候,就与后者冲突了】,2.是从第二层跳1阶上来,总共F(3)=F(2)+F(1))
public int JumpFloor(int target) {if(target==1){return 1;}else if(target==2){return 2;}else{int a=1;int b=2;int f=0;for(int i=3;i<=target;i++){f=a+b;a=b;b=f;}return f;} }
9..变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
(难点在于,推算出f(n)=2f(n-1),如果用f(n)=f(n-1)+f(n-2)。。。。。f(0)来递归,运算时间过长过长。可以尝试用动态规划来做,用数组来存中中间运算出来的数值,明天尝试。)
public int JumpFloorII(int target) {if(target==1){return 1;}else{return 2*JumpFloorII(target-1); } }
9.2用循环实现,不知这样能不能称之为动态规划,还需对动态规划的概念在进行了解。
/*思路,用一个数组来记录所有的f(n),f(n-1).....f(0)*/
public int JumpFloorII(int target) {if(target==0){return 1;}else{int[] k=new int[target+1];k[0]=1;for(int i=1;i<=target;i++){for(int j=0;j<i;j++){k[i]=k[i]+k[j];}}return k[target];} }
10.矩形覆盖
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?(思路同青蛙跳台阶,也为斐波那契数列)
public int RectCover(int target) {if(target<=2){return target;}else{int a=2;//f(n-1)int b=1;//f(n-2)int f=0;//f(n)for(int i=3;i<=target;i++){f=a+b;//f(n)=f(n-1)+f(n-2)b=a;//更新b为f(n-1);用于下轮循环,下轮为f(n+1)=f(n)+f(n-1)a=f;//更新a为f(n);用于下轮循环,下轮为f(n+1)=f(n)+f(n-1)}return f;} }
11.二进制中1的个数
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
(思路,让该数,与1做与运算,得1,count++,之后该数,向右移一位,高位要补零,防止负数高位补1要用>>>来移位,高位只补零)
public int NumberOf1(int n) { int flag=1; int count=0; while(n!=0){ if((n&flag)==1){ count++; } n>>>=1; } return count; }
12..数值的整数次方
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
(思路:举例2^13相当于10^1101=10^0001*10^0100*10^1000=2^1*2^4*2^8=2^1*(2^2)^0*(2^2^2)^1*(2^2^2^2)^1(移一次位,基数要平方一次),我们就可以通过,操作二进制的方式,来做,这样做,多大的int型的次方,都可以在32次循环内,得出结果。)
public double Power(double base, int exponent) { int n=exponent; double base2=base; double result=1; if(exponent<0){ if(base==0){ throw new RuntimeException("零不能做分母"); } n=-exponent; }else if(exponent==0){ return 1; } while(n!=0){ if((n&1)==1) result*=base2;// base2*=base2;//比如2^13=2^1*2^4*2^8=2^1*4^0*16^1*256^1;每次移动一位,都要把基数来一次平方。 n>>>=1; } return exponent>0?result:(1/result); }
- 剑指Offer算法题JAVA版4-12题(全是个人写的非官方,只供参考和自己复习,测试用例都通过了)
- 剑指Offer算法题JAVA版13-20题(全是个人写的非官方,只供参考和自己复习,测试用例都通过了。)
- 剑指Offer算法题JAVA版21-30题(全是个人写的非官方,只供参考和自己复习,测试用例都通过了。)
- JDBC基础知识(供个人我自己参考,来自网络。)
- 项目管理心得:一个项目经理的个人体会、经验总结 (供自己参考)
- 自己js写的分页小工具供大家参考
- Uri,Url,Urn,src,href的解释和区别,个人查资料理解,不严谨,只供参考
- hadoop个人笔记,仅供自己参考
- sqlserver知识点汇总(这段时间复习和回顾了一下sqlserver的一些知识),供大家参考和学习!
- 七牛java自己写的pfop操作,非官方sdk。
- Calendar类学习,自己写了个日历查询小程序,供大家学习参考
- mysql参考(仅供自己参考)
- enum枚举的试用笔记 (仅供个人参考)
- Springmvc遇到的问题和解决方案(仅供自己参考,不喜勿喷)
- 开始学习Matlab,一点一滴记录自己的所学 仅供个人参考Matlab(1)
- 条件变量的文章(供自己参考)
- 条件变量的文章(供自己参考)
- SSH中主要的配置文件记录,省得自己以后忘了,供自己参考
- iOS中的单例模式
- 秒懂github的pull request
- Struts2的处理流程
- NOIP提高组2015 飞扬的小鸟
- 圣邦微新产品发布1.5A 闪光灯驱动:SGM3785
- 剑指Offer算法题JAVA版4-12题(全是个人写的非官方,只供参考和自己复习,测试用例都通过了)
- java中Object转String
- 2016-7-2日总结
- BZOJ3626 [LNOI2014]LCA
- libuv学习笔记(22)
- 动态菜单栏
- MFC进度栏的编程(SDI)
- 静态变量
- iOS开发思想