刷题笔记【2】| 快速刷完67道剑指offer(Java版)

在这里插入图片描述

本文已收录于专栏
《刷题笔记》

文章目录

  • 前言
  • 1、重建二叉树
    • 题目描述
    • 思路(递归)
  • 2、用两个栈来实现一个队列
    • 题目描述
    • 思路
  • 3、旋转数组
    • 题目描述
    • 思路一(暴力破解)
    • 思路二
    • 思路三(二分)

前言

题目来源参考阿秀学长的刷题笔记,小戴只是把 C++的题解改成了 Java版本,并整理了其他思路,便于自己的学习~

如果解题有更好的方法,本文也会及时进行更新~

希望对你有帮助~ 一起加油哇~

1、重建二叉树

牛客原题链接

题目描述

给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。

思路(递归)

首先,我们需要熟悉二叉树遍历的规则
前序:中左右;前序:左中右;后序:左右中

  1. 根据前序遍历的结果,马上确定第一个是根结点
  2. 在中序结果中找到根结点位置,根结点左右分别对应这个结点的左右子树
  3. 不断递归返回每个子树的根结点,从而构建整个二叉树
刷题笔记【2】| 快速刷完67道剑指offer(Java版)_第1张图片
import java.util.*;
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre, int [] vin) {
        if (pre.length == 0 || vin.length == 0) {
            return null;
        }
        // 构建根结点
        TreeNode root = new TreeNode(pre[0]);
        for (int i = 0; i < vin.length; i++) {
            // 在 中序遍历中 找到根结点位置
            if (pre[0] == vin[i]) {
                // 左子树
                root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(vin,0, i));
                // 右子树
                root.right =reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(vin,i+1, vin.length));
                break;
            }
        }
        return root;

    }
}

Arrays.copyOfRange(pre, 1, i + 1)

这个意思就是把某数组的指定范围复制到另一个新数组中,结合本句:

把 pre 数组下标为1到下标为i的范围复制到新数组中,注意:包括下标1,不包括下标i+1

2、用两个栈来实现一个队列

牛客原题链接

题目描述

用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素

思路

这道题很简单!!!用两个栈模拟实现队列的push和pop操作

队列push操作:
直接用stack1 这个栈用来存队列push 过来的数据

队列pop操作:
先判断stack2是否为空,为空的话,不断把stack1的顶部数据弹出到stack2,直到stack1为空,最后返回stack2的顶部数据;stack2不为空,直接返回顶部数据

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

3、旋转数组

牛客原题链接

题目描述

有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值

思路一(暴力破解)

直接遍历,找最小的

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array.length == 0) return 0;
        if(array.length == 1) return array[0];
        // 最小值
        int minNum = array[0];
        for(int i=1; i<array.length; i++){
            if(array[i] < minNum) return array[i];
        }
        return minNum;
    }
}

思路二

这个旋转数组,前面一部分肯定是递增的,然后递减一下,在递增

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array.length == 0) return 0;
        if(array.length == 1) return array[0];
        for(int i=0; i<array.length-1; i++){
            if(array[i] > array[i+1]) return array[i+1];
        }
        return array[0];
    }
}

思路三(二分)

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array.length == 0) return 0;
        if(array.length == 1) return array[0];
        int left=0, right=array.length-1;
        while(left<right){
            int mid = left + (right-left)/2;
            if(array[mid] < array[right]){
                right = mid;
            }else if(array[mid] > array[right]){
                left = mid + 1;
            }else{
                right--;
            }
        }
        return array[left];
    }
}

你可能感兴趣的:(刷题笔记,算法,leetcode,java)