剑指Offer练习题目(一)[牛客网的剑指offer题目1~10]

剑指Offer练习题目(一)

简介:牛客网的剑指offer题目1~10

题目目录:
  • 1.二维数组中的查找
  • 2.替换空格
  • 3.从尾到头打印链表
  • 4.重建二叉树
  • 5.用两个栈实现队列
  • 6.旋转数组的最小数字
  • 7.斐波那契数列
  • 8.跳台阶
  • 9.变态跳台阶
  • 10.矩形覆盖

import org.junit.Test;

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

/**
 * @program: niuke-test
 * @description: 复习之前的题目
 * @create: 2020-04-15 08:50
 **/
public class review01 {

    /* ----------1---------- */
    /* 
    * @Description:
    在一个二维数组中(每个一维数组的长度相同),
    每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
    请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
    1 2 8 9             
    2 4 9 12
    4 7 10 13     9
    6 8 11 15
    */
    //方法1.全部遍历
    public boolean Find1(int target, int [][] array) {
        int length = array.length;
        int width = array[0].length;
        for (int i=0;i<width;i++){
            for(int j=0;j<length;j++){
                if(target == array[i][j]){
                    return true;
                }
            }
        }
        return false;
    }
    //方法2.按照数组特点来查找,从左下角开始找
    public boolean Find2(int target, int [][] array) {
       int line = array.length-1;
       int row = 0;
       while(line>=0 && row<=array[0].length-1){
            if(target == array[line][row]){
                return true;
            }else if(target > array[line][row]){
                row++;
            }else {
                line--;
            }
       }
       return false;

    }

    @Test
    public void testFind2(){
        int targer = 15;
        int[][] array = {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
        Find2(targer,array);
    }

    /* ----------2---------- */

    /*
    * @Description: 请实现一个函数,将一个字符串中的每个空格替换成“%20”。
    * 例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
    */

    public String replaceSpace1(StringBuffer str) {
        String string = str.toString();
        return string.replaceAll(" ","%20");
    }

    public String replaceSpace2(StringBuffer str) {
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<str.length();i++){
            if(str.charAt(i)!=' '){
                sb.append(str.charAt(i));
            }else{
                sb.append("%20");
            }
        }
        return sb.toString();
    }

    @Test
    public void testReplaceSpace(){
        StringBuffer sb =  new StringBuffer("We Are Happy");
        System.out.println(replaceSpace2(sb));
    }

    /* ----------3---------- */

    /*
    * @Description:  输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
    */
    public class ListNode {
        int val;
        ListNode next = null;

        ListNode(int val) {
            this.val = val;
        }
    }
    //方法1.利用栈的特点输出
    public ArrayList<Integer> printListFromTailToHead1(ListNode listNode) {
        Stack<Integer> stack = new Stack<>();
        ArrayList<Integer> list = new ArrayList<>();
        if(listNode == null){
            return list;
        }
        while(listNode!=null){
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        while(!stack.isEmpty()){
            list.add(stack.pop());
        }
        return list;
    }
    //方法2.头插法
    public ArrayList<Integer> printListFromTailToHead2(ListNode listNode) {
            ListNode head  =  new ListNode(0);
            ListNode pre ;
            ArrayList<Integer> list = new ArrayList<>();
            while(listNode!=null){
                pre = listNode;
                listNode = listNode.next;
                pre.next = head.next;
                head.next = pre;

            }
            head = head.next;
            while(head!=null){
                list.add(head.val);
                head = head.next;
            }
            return list;
    }

    @Test
    public void testPrintListFromTailToHead(){
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3= new ListNode(3);
        ListNode node4 = new ListNode(4);
        ListNode node5= new ListNode(5);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        ArrayList<Integer> list = printListFromTailToHead2(node1);
        System.out.println(list.toString());
    }

    /* ----------4---------- */

    /*
    * @Description: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
    * 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
    * 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
    * 则重建二叉树并返回。
    */
    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]);
        int index = 0;
        for(int i=0;i<in.length;i++){
             if(pre[0] == in[i]){
                    index = i;
                    break;
                }
        }


        node.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,index+1),Arrays.copyOfRange(in,0,index));
        node.right = reConstructBinaryTree(Arrays.copyOfRange(pre,index+1,pre.length),Arrays.copyOfRange(in,index+1,in.length));
        return node;

    }

    @Test
    public void testReConstructBinaryTree(){
        int [] pre = {1,2,4,7,3,5,6,8};
        int [] in = {4,7,2,1,5,3,8,6};
        TreeNode node = reConstructBinaryTree(pre,in);
        System.out.println(node.toString());
    }

    /* ----------5---------- */

    /*
    * @Description: 用两个栈来实现一个队列,
    * 完成队列的Push和Pop操作。 队列中的元素为int类型。
    */

        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.size()>0){
                    stack2.push(stack1.pop());
                }
            }


            return stack2.pop();
        }

        @Test
        public void tets(){
            push(1);
            push(2);
            System.out.println(pop());
            push(3);
            System.out.println(pop());
            System.out.println(pop());
        }

     /* ----------6---------- */

    /*
    * @Description: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
        输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
        例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
        NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

    */
    public int minNumberInRotateArray(int [] array) {
        if(array.length == 0){
            return 0;
        }
        int letf = 0;
        int right = array.length-1;
        int mid=0;
        while(letf<right){

            if(array[letf]<array[right]){
                mid = (letf+right)/2;
                right = mid;
            }else{
                mid = (letf+right)/2;
                letf = mid;
            }
        }
        return array[mid];

    }

    @Test
    public void testMinNumberInRotateArray(){
        int[] array = {3,4,5,6,7,0,1,2};
        System.out.println(minNumberInRotateArray(array));
    }


     /* ----------7---------- */
    /*
    * @Description: 大家都知道斐波那契数列,现在要求输入一个整数n,
    * 请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
    * 斐波那契数列:从第三项开始,后一项是前两项的和
    */
     public int Fibonacci(int n) {
        if(n == 0){
            return 0;
        }
        if(n == 2 || n == 1){
            return 1;
        }
        return Fibonacci(n-1)+Fibonacci(n-2);
     }

     @Test
     public void testFibonacci(){
         System.out.println(Fibonacci(39));
     }

     /* ----------8---------- */
     /*
     * @Description: 一只青蛙一次可以跳上1级台阶,也可以跳上2级。
     * 求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
     * 一阶:1
     * 二阶:2
     * 三阶:3
     * 四阶:5
     */
     public int JumpFloor(int target) {
        if(target == 0){
            return 0;
        }
        if(target == 1){
            return 1;
        }
        if(target == 2){
            return 2;
        }
        return JumpFloor(target-1)+JumpFloor(target-2);

     }

     /* ----------9---------- */
     /*
     * @Description: 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
     * 求该青蛙跳上一个n级的台阶总共有多少种跳法。
     * 一阶:1
     * 二阶:2
     * 三阶:4
     * 四阶:8
     */
     public int JumpFloorII(int target) {
        if(target == 0){
            return 0;
        }
        if(target == 1){
            return 1;
        }
        return 2*JumpFloorII(target-1);
     }

     /* ----------10---------- */
     /*
     * @Description:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
     * 请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
        比如n=3时,2*3的矩形块有3种覆盖方法:
        n=1: 1
        n=2: 2
        n=3: 3
        n=4: 5
     */
     public int RectCover(int target) {
        if(target == 0){
            return 0;
        }
        if(target ==1){
            return 1;
        }
        if(target ==2){
            return 2;
        }
        return RectCover(target-1)+RectCover(target-2);
     }






}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值