剑指offer 1-5

Posted lgh544

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer 1-5相关的知识,希望对你有一定的参考价值。

1二维数组的查找:

  在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

 

一、暴力法

时间复杂度:技术图片
空间复杂度:O(1)

二、从左下找

利用该二维数组的性质:

  • 每一行都按照从左到右递增的顺序排序,
  • 每一列都按照从上到下递增的顺序排序

改变个说法,即对于左下角的值 m,m 是该行最小的数,是该列最大的数
每次将 m 和目标值 target 比较:

  1. 当 m < target,由于 m 已经是该行最大的元素,想要更大只有从列考虑,取值右移一位
  2. 当 m > target,由于 m 已经是该列最小的元素,想要更小只有从行考虑,取值上移一位
  3. 当 m = target,找到该值,返回 true

用某行最小或某列最大与 target 比较,每次可剔除一整行或一整列

时间复杂度:技术图片
空间复杂度:O(1)

//二维数组的查找
public class theSeekOfTwodDmensionalArray {

    public static void main(String[] args) {
        theSeekOfTwodDmensionalArray seek = new theSeekOfTwodDmensionalArray();
        int target = 12;
        int[][] array = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
        boolean flag = seek.Find(target, array);
        System.out.println(flag);
    }
     public boolean Find(int target, int [][] array) {
         boolean flag = false;
         int row = array.length-1;
         int col = 0;
         while(row >= 0 && col <=array[0].length-1) {
             if(array[row][col] < target) {
                 col++;
             }else if(array[row][col] > target) {
                 row--;
             }else {
                 return true;
         }
     }
         return false;
}
}

2替换空格

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

  一、调用自带函数

  二、用新的數組存

当遇到 " ",就追加 "%20",否则遇到什么追加什么

public class replaceSpaceTest {

    public static void main(String[] args) {
        replaceSpaceTest replacespace = new replaceSpaceTest();
        String str = "dog is animal";
        StringBuffer stringbuffer = new StringBuffer(str);
        String s = replacespace.replaceSpace(stringbuffer);
        System.out.println(s);
    }
        //调用库函数
    public String replaceSpace1(StringBuffer str) {
                return str.toString().replace(" ", "%20");
            }
        //追加
    public String replaceSpace(StringBuffer str) {
        StringBuilder stringbuilder = new StringBuilder();
        for(int i =0; i < str.length();i++) {
            if(str.charAt(i) == ‘ ‘) {
                stringbuilder.append("%20");
            }else {
                stringbuilder.append(str.charAt(i));
            }
        }
        return stringbuilder.toString();
    }

}

3从尾到头打印链表

  输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

使用ArrayList的add(index,value)

import java.util.ArrayList;

public class printListFromTailToHeadTest {

    public static void main(String[] args) {
        printListFromTailToHeadTest print = new printListFromTailToHeadTest();
        link l = new link();
        for(int i = 0;i < 10;i++) {
            l.add(i);
        }
        ArrayList<Integer> res = print.printListFromTailToHead(l.root);
        System.out.println(res.toString());
        
    }
     public ArrayList<Integer> printListFromTailToHead(ListNode listNode){
         ArrayList<Integer> list = new ArrayList<>();
         while(listNode != null) {
             list.add(0,listNode.val);
             listNode = listNode.next;
         }
         return list;
     }

}
//链表添加结点
class link{
    public ListNode root;
    public void add(int val) {
        ListNode listNode = new ListNode(val);
        if(this.root == null) {
            this.root = listNode;
        }else {
            this.root.add(listNode);
        }
    }
}
    class ListNode{
    int val;
    ListNode next;
    
    public ListNode(int val) {
        this.val = val;
    }
    public void add(ListNode listNode) {
        if(this.next == null) {
            this.next = listNode;
        }else {
            this.next.add(listNode);
        }
        
    }
}

 

4重建二叉树

根据中序遍历和前序遍历可以确定二叉树,具体过程为:

  1. 根据前序序列第一个结点确定根结点
  2. 根据根结点在中序序列中的位置分割出左右两个子序列
  3. 对左子树和右子树分别递归使用同样的方法继续分解

例如:
前序序列{1,2,4,7,3,5,6,8} = pre
中序序列{4,7,2,1,5,3,8,6} = in

    1. 根据当前前序序列的第一个结点确定根结点,为 1
    2. 找到 1 在中序遍历序列中的位置,为 in[3]
    3. 切割左右子树,则 in[3] 前面的为左子树, in[3] 后面的为右子树
    4. 则切割后的左子树前序序列为:{2,4,7},切割后的左子树中序序列为:{4,7,2};切割后的右子树前序序列为:{3,5,6,8},切割后的右子树中序序列为:{5,3,8,6}
    5. 对子树分别使用同样的方法分解
    6. 时间复杂度:O(n)O(n)O(n)
      空间复杂度:O(n)O(n)O(n)
import java.util.Arrays;

public class reconstructionOfBinaryTree {

    public static void main(String[] args) {
        reconstructionOfBinaryTree binaryTree = new reconstructionOfBinaryTree();
        int[] pre = {1,2,4,7,3,5,6,8};
        int[] in = {4,7,2,1,5,3,8,6};
         TreeNode root = binaryTree.reConstructBinaryTree(pre,in);
         root.preOrder();
    }
    //递归
    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]) {
                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));
                break;
            }
        }
        return node;
    }
}
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    public TreeNode(int val) {
        this.val = val;
    }
    //验证构建的二叉树  前序遍历
    public void preOrder() {
        System.out.println(this.val);
        if(this.left != null) {
            this.left.preOrder();
        }
        if(this.right != null) {
            this.right.preOrder();
        }
    }
}

5用两个栈模拟队列

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

      • 当插入时,直接插入 stack1
      • 当弹出时,当 stack2 不为空,弹出 stack2 栈顶元素,如果 stack2 为空,将 stack1 中的全部数逐个出栈入栈 stack2,再弹出 stack2 栈顶元素
      • push时间复杂度:技术图片
        pop空间复杂度:O(1)
import java.util.Stack;

public class twoStacksAnalogqueue {

    public static void main(String[] args) {
        twoStacksAnalogqueue stack = new twoStacksAnalogqueue();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        System.out.println(stack.pop());
        stack.push(4);
        System.out.println(stack.pop());
        stack.push(8);
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        
    }

    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();
    }
}

 

以上是关于剑指offer 1-5的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer(三十三)之重建二叉树

剑指offer重建二叉树python

[剑指offer] 重建二叉树

《剑指offer》— JavaScript重建二叉树

重建二叉树-剑指Offer

剑指offer 1-5