剑指Offer详细题解 01-10

声明:内容较多, 没耐心的小伙伴先码后看

官方C语言题解:https://github.com/zhedahht/CodingInterviewChinese2

01.赋值运算符

这个就不用写了爬

02.手写单例

直接参考cyc的博客就好:https://github.com/CyC2018/CS-Notes/blob/master/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20%20-%20%E5%8D%95%E4%BE%8B.md

03.数组中重复的数字

/**
 * @Description  03 数组中重复的数字 -小米有品
 * @Author Zerah
 * @Date 2019/11/11 16:41
 **/
public class _03_DuplicationInArray {
    public boolean dublicate(int [] nums , int length, int [] duplication){
        // 入参数组校验
        if (nums == null || nums.length<=0){
            return false;
        }
        // 数组中元素校验
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] <0 || nums[i] > length-1){
                return false;
            }
        }
        for (int i = 0; i < nums.length; i++) {
            //当前下标i处存的元素不是i
            while (nums[i] != i){
                // 当前下标处的元素 和 下表为 num[i]处下标元素相等的话,说明存在重复元素
                if (nums[i] == nums[nums[i]]){
                    duplication[0] = nums[i];
                    return true;
                }
                //交换元素
                swap(nums, i, nums[i]);
            }
        }
        return false;
    }
    private void swap(int nums[], int i, int j){
        int t = nums[i];
        nums [i] = nums[j];
        nums [j] = t;
    }

}

04.二维数组中的查找

/**
 * @Description 二维数组中的查找
 * @Author Zerah
 * @Date 2019/11/11 16:56
 **/
public class _04_FindInPartiallySortedMatrix {
    public boolean findTarget(int target , int [][] matrix){
        //入参数组校验
        if (matrix == null || matrix.length == 0 || matrix[0].length ==0){
            return false;
        }
        int rows = matrix.length;
        int cols = matrix[0].length;
        //从右上角开始,同理,可从左上角,左下角,右下角开始
        int r =0,c = cols-1;
        while (r <= rows -1 && c >=0){
            if (target == matrix[r][c]){
                return true;
            }else if( target> matrix[r][c]){
                r++;
            }else if (target < matrix[r][c]){
                c--;
            }
        }
        return false;
    }
}

05.替换空格

/**
 * @Description 替换空格
 * @Author Zerah
 * @Date 2019/11/12 10:32
 **/
public class _05_ReplaceSpaces {
    public String replaceSpaces(String str){
        if (str == null || str.length()<= 0){
            return null;
        }
        StringBuilder sb = new StringBuilder(str);
        //P1指向原始字符串的末尾索引,可以把字符串看作数组
        int P1 = sb.length()-1;
        for (int i=0; i<= P1; i++){
            // 遍历的原始字符串中如果有空格
            if (sb.charAt(i)==' '){
                //因为 空格‘ ’ 替换为 ”%20“ 长度增加了2, 因此此处在字符串末尾拼接两个空格
                sb.append("  ");
            }
        }
        //P2指向扩容后的新字符串的末尾索引
        int P2 = sb.length()-1;
        //P1遍历到原始字符串开头,并且 P1和P2相遇后结束
        while (P1>= 0 && P2>P1){
            char c = sb.charAt(P1--);
            //如果遇到空格,替换空格
            if (c == ' '){
                sb.setCharAt(P2--,'0');
                sb.setCharAt(P2--,'2');
                sb.setCharAt(P2--,'%');
            }else {
                //否则 将原始字符串中的字符迁移到扩容后的位置
                sb.setCharAt(P2--,c);
            }
        }
        return sb.toString();
    }
}

06.从尾到头打印链表

/**
 * @Description 06.从尾到头打印链表
 * @Author Zerah
 * @Date 2019/11/12 11:10
 **/
public class _06_PrintListInReverseOrder {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode){
        Stack<Integer> stack = new Stack<>();
        // 校验,入栈
        while (listNode !=null){
            stack.add(listNode.val);
            listNode = listNode.next;
        }
        ArrayList<Integer> ret = new ArrayList<>();
        // 出栈,并且存入ArrayList
        while (!stack.isEmpty()){
            ret.add(stack.pop());
        }
        return ret;
    }
    public class ListNode{
        private Integer val;
        private ListNode next;
    }
}

07.重建二叉树

前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两个部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历结果

/**
 * @Description 07.重建二叉树
 * @Author Zerah
 * @Date 2019/11/12 15:51
 **/
public class _07_ConstructBinaryTree {
    // 缓存中序遍历数组
    private Map<Integer,Integer> indexForInOrders = new HashMap<>();

    /**
     *
     * @param pre 前序数组
     * @param in  中序数组
     * @return
     */
    public TreeNode reConstructBinaryTree(int [] pre, int[] in){
        for (int i=0; i<in.length; i++){
            //中序遍历的数顺序put进map中
            indexForInOrders.put(in[i],i);
        }
        return reConstructBinaryTree(pre,0,pre.length-1, 0);
    }
    private TreeNode reConstructBinaryTree(int []pre, int preL, int preR, int inL){
        if (preL > preR){
            return null;
        }
        TreeNode root = new TreeNode(pre[preL]);
        int inIndex = indexForInOrders.get(root.val);
        int leftTreeSize = inIndex - inL;
        root.left = reConstructBinaryTree(pre,preL+1, preL + leftTreeSize, inL);
        root.right = reConstructBinaryTree(pre, preL + leftTreeSize+1, preR, inL+leftTreeSize +1);
        return root;

    }
    static class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;
        public TreeNode(int node){
            this.val = node;
        }
    }

    public static void main(String[] args) {
        int pre[] = {3,9,20,15,7};
        int in[] = {9,3,15,20,7};
        _07_ConstructBinaryTree tree = new _07_ConstructBinaryTree();
        TreeNode treeNode = tree.reConstructBinaryTree(pre, in);
        System.out.println(treeNode);
    }
}

09.用两个栈实现队列

思路参考:https://blog.csdn.net/csdnnews/article/details/86570636

package com.zerah.concurrent.ToOffer;

import java.util.Stack;

/**
 * @Description  使用两个栈实现队列
 * @Author Zerah
 * @Date 2019/12/16 17:31
 **/
public class _09_QueueWith2Stack {
    Stack<Integer> in = new Stack<>();
    Stack<Integer> out = new Stack<>();

    /**
     * 入队 O(1)
     * @param node
     */
    public void push(int node){
        in.push(node);
    }

    /**
     * 出队 O(n)
     * @return
     */
    public int pop(){
        if (out.isEmpty()){
            while (!in.isEmpty()){
                out.push(in.pop());
            }
        }
        if (out.isEmpty()){
            return -1;
        }
        return out.pop();
    }

    /**
     * 判空
     * @return
     */
    public boolean isEmpty(){
        return in.isEmpty() && out.isEmpty();
    }

}

10.斐波那契数列

这个题也是在美团三面挂了的题,只恨当时蠢,至写出了递归,面试官又问了循环实现,以及当这个数很大时怎么处理的思路,因为这个题,三面给挂了,哭了,所以小伙伴们不仅仅要会解体,简单的题要有优化的思路offer才更有保障,引以为戒

package com.zerah.concurrent.ToOffer;

/**
 * @Description 斐波那契数列
 * @Author Zerah
 * @Date 2019/12/17 12:32
 **/
public class _10_Fibonacci {
    /**
     * 递归实现
     * @param n
     * @return
     */
    public static int fibonacci_self(int n){
        if (n <= 0){
            return 0;
        }
        if (n ==1 ){
            return 1;
        }
        return fibonacci_self(n-1)+ fibonacci_self(n-2);
    }

    /**
     * dp 实现,将自问题的解缓存起来,避免重复求解子问题
     * @param n
     */
    public static int fibonacci_dp(int n){
        if(n<=1){
            return n;
        }
        int [] fib = new int[n+1];
        fib[1] =1;
        for (int i=2;i<=n ; i++){
            fib[i] = fib[i-1]+ fib[i-2];
        }
        return fib[n];
    }

    /**
     * 循环实现 ;因为 fib(i) 只和fib(i-1)以及fib(i-2)有关,因此可以通过前两个值从下而上解决问题
     * @param n
     */
    public static int fibonacci_for(int n){
        if (n<=1) return n;
        int pre =0,curr=1;
        int fib = 0;
        for (int i=2; i<= n; i++){
            fib = pre+ curr;

            pre =curr;
            curr =fib;
        }
        return fib;
    }


    public static void main(String[] args) {
        System.out.println(fibonacci_self(6));
        System.out.println(fibonacci_dp(6));
        System.out.println(fibonacci_for(6));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值