牛客剑指offer前10道题

package com.dixin.temp;
/**
 * Created by admin on 2017/10/22.
 */

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Stack;

public class D {
    /**
     * 10 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示
     *  http://15838341661-139-com.iteye.com/blog/1642525
     */
    public int NumberOf1(int n) {
        int count=0;
        while(n!=0) {
            n=n&(n-1);
            count++;
        }
        return count;
    }
    @Test
    public void test9() {
        System.out.print(NumberOf1(-1));
    }

    /**
     * 9 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
     *  请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
     *
     *  总结:如果用1*m的方块覆盖m*n区域,递推关系式为f(n) = f(n-1) + f(n-m),(n > m)
     */
    public int RectCover(int target) {
        if(target==0||target==1||target==2) {
            return target;
        }
        return RectCover(target-1)+RectCover(target-2);
    }

    /**
     * 8 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
     * 求该青蛙跳上一个n级的台阶总共有多少种跳法。
     * 思路一 :
     * 因为n级台阶,第一步有n种跳法:跳1级、跳2级、到跳n级
     * 跳1级,剩下n-1级,则剩下跳法是f(n-1)
       跳2级,剩下n-2级,则剩下跳法是f(n-2)
       所以f(n)=f(n-1)+f(n-2)+...+f(1)
       因为f(n-1)=f(n-2)+f(n-3)+...+f(1)
       所以f(n)=2*f(n-1)
     * 思路二 :
       每个台阶都有跳与不跳两种情况(除了最后一个台阶)
       最后一个台阶必须跳。所以共用2^(n-1)中情况
     */
    public int JumpFloorII(int target) {
        if(target==1) {
            return target;
        }
        return 2*JumpFloorII(target-1);
    }

    /**
     * 7 一只青蛙一次可以跳上1级台阶,也可以跳上2级。
     * 求该青蛙跳上一个n级的台阶总共有多少种跳法。
     * tip:当前台阶的跳法总数=当前台阶后退一阶的台阶的跳法总数+当前台阶后退二阶的台阶的跳法总数
     */
    public int JumpFloor(int target) {
        if(target==1||target==2) {
            return target;
        }
        return JumpFloor(target-1)+JumpFloor(target-2);
    }
    @Test
    public void test6() {
        System.out.println(JumpFloor(5));
    }


    /**
     * 6要求输入一个整数n,请你输出斐波那契数列的第n项。
     */
    public int Fibonacci(int n) {
        if(n==0|n==1) {
            return n;
        }
        return Fibonacci(n-1)+Fibonacci(n-2);
    }
    @Test
    public void test5() {
        int a=Fibonacci(6);
        System.out.print(a);
    }


    class ListNode {
        int val;
        ListNode next=null;
        ListNode(int val) {
            this.val=val;
        }
    }
    /**
     * 5 输入一个链表,从尾到头打印链表每个节点的值。
     */
    //@1借助堆栈的后入先出原则
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        Stack<Integer> stack=new Stack<>();
        while(listNode!=null) {
            stack.push(listNode.val);
            listNode=listNode.next;
        }
        ArrayList<Integer> list=new ArrayList<>();
        while(!stack.isEmpty()) {
            list.add(stack.pop());
        }
        return list;
    }

    //@2借助递归实现(递归的本质还是使用了堆栈结构)
    public ArrayList<Integer> printListFromTailToHead2(ListNode listNode) {
        ArrayList<Integer> list=new ArrayList<>();
        if(listNode!=null) {
            if(listNode.next!=null) {
                list=printListFromTailToHead2(listNode.next);
            }
            list.add(listNode.val);
        }

        return list;
    }
    @Test
    public void test4() {
        ListNode node=new ListNode(1);
        node.next=new ListNode(2);
        node.next.next=new ListNode(3);
        ArrayList<Integer> list1=printListFromTailToHead2(node);
        for(Integer node1:list1) {
            System.out.print(node1);
        }
    }


    /**
     * Definition for binary tree
     * 4 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树
     */
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) {
            val = x;
        }
    }
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre.length==0||in.length==0) {
            return null;
        }
        TreeNode node=new TreeNode(pre[0]);
        for(int i=0;i<in.length;i++) {
            if(in[i]==pre[0]) {
                //Arrays.copyOfRange将一个原始的数组original,从小标from开始复制,复制到小标to,生成一个新的数组。
                //注意这里包括下标from,不包括下标to。
                node.left=reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
                node.right=reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
            }
        }
        return node;
    }

    @Test
    public void test3() {
        int [] pre={1,2,4,7,3,5,6,8};
        int [] in={4,7,2,1,5,3,8,6};
        TreeNode treeNode=reConstructBinaryTree(pre,in);
    }



    /**
     * 3  旋转数组的最小数字
     * 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素
     * @param array
     * @return
     */
    public int minNumberInRotateArray(int [] array) {
        if(array.length==0) {
            return 0;
        }
        int low=0;
        int hi=array.length-1;
        while (low<hi) {
            int mid=(low+hi)/2;
            if(array[mid]>array[hi]) {//最小值一定在mid右边
                low=mid+1;
            } else if(array[mid]<array[hi]) {//最小值是mid或者在mid的左边
                hi=mid;
            } else {//这种不好判断,将hi,减一再接着查找
                hi=hi-1;
            }
        }
        return array[low];//最后返回最小值
    }
    @Test
    public void test2() {
        int a[]={1,2,3,2,3};
        int i=minNumberInRotateArray(a);
        System.out.println(i);
    }


/**
 * Created by admin on 2017/10/12.
 * 1将一个字符串中空格替换成%20
 */

    private StringBuffer str=new StringBuffer("We are happy");
    @Test
    public void test() {
        String z=replaceSpace(str);
        System.out.println(z);
    }

    public String replaceSpace(StringBuffer str) {
        char[] a=str.toString().toCharArray();
        StringBuffer out=new StringBuffer();
        for(int i=0;i<a.length;i++) {
            if(a[i]==' ') {
                out.append("%20");
            } else {
                out.append(a[i]);
            }
        }
        return out.toString();
    }


    /**
     * 2两个栈实现队列
     */
    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());
            }
        }
        return stack2.pop();
    }
    @Test
    public void test1() {
        push(1);
        push(3);
        push(5);
        System.out.print(pop());
        System.out.print(pop());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值