目录
- [一、BM21 旋转数组的最小数字](#一、BM21 旋转数组的最小数字)
- [二、BM22 比较版本号](#二、BM22 比较版本号)
- [三、BM23 二叉树的前序遍历](#三、BM23 二叉树的前序遍历)
- [四、BM24 二叉树的中序遍历](#四、BM24 二叉树的中序遍历)
- [五、BM25 二叉树的后序遍历](#五、BM25 二叉树的后序遍历)

一、BM21 旋转数组的最小数字
题目链接:BM21 旋转数组的最小数字
题目描述:

题目解析:
- 旋转数组:本质是升序数组(有相同元素值),从头截取一段子数组放到末尾,该数组就变成了两段升序数组,并且第二段的最大值一定小于等于第一段最小值
- 求最小值
解题思路:
- 使用二分法,利用特性第二段升序数组元素一定小于等于第一段。mid与right 元素值比大小
- mid元素大,证明最小值在 mid+1, right中
- mid元素小,证明最小值在 left, mid中
- 元素值相同,right减一缩小范围(因为numsright这个值还在二分范围中即numsmid)。
解题代码:
java
//时间复杂度:O(logN)
//空间复杂度:O(1)
import java.util.*;
public class Solution {
public int minNumberInRotateArray (int[] nums) {
int left = 0;
int right = nums.length-1;
if(right == 0) return 0;
while(left < right) {
int mid = (left + right) / 2;
if(nums[mid] < nums[right]) {
right = mid;
} else if(nums[mid] > nums[right]) {
left = mid+1;
} else {
right--;
}
}
return nums[right];
}
}
二、BM22 比较版本号
题目链接:BM22 比较版本号
题目描述:

题目解析:
- 给我们两个字符串,将由
.逗号隔开的子字符串进行从从前到后一一比较大小,子字符串会有前导0,会出现子字符串数量不一致情况,相同的子字符串全部相同,还有剩余的大。
解题思路:
- 循环遍历两个字符串直到都走到末尾,去拿每一个子字符串的值,进行比较即可。
- 拿每一个子字符串的值(单独方法):处理前导零,拿到子字符串值并返回这个值,跳过
.逗号,更新当前遍历的下标 - 循环遍历:那每一个子字符串的值时,确保当前数组没越界,比较子字符串值即可
- 当前遍历到的下标值我们使用一个hash表或者数组来存即可。
解题代码:
java
//时间复杂度:O(N)
//空间复杂度:O(1)
import java.util.*;
public class Solution {
private HashMap<String, Integer> hash = new HashMap<>();
public int compare (String version1, String version2) {
hash.put("v1", 0);
hash.put("v2", 0);
int len1 = version1.length();
int len2 = version2.length();
while (hash.get("v1") < len1 || hash.get("v2") < len2) {
int index1 = hash.get("v1");
int index2 = hash.get("v2");
int num1 = 0;
if (index1 < len1) {
num1 = judge(version1, index1, len1, "v1");
}
int num2 = 0;
if (index2 < len2) {
num2 = judge(version2, index2, len2, "v2");
}
if (num1 > num2) return 1;
else if (num1 < num2) return -1;
}
return 0;
}
private int judge(String version, int left, int right, String v) {
int index = left;
// 跳过前导零
while (index < right && version.charAt(index) == '0') {
index++;
}
int num = 0;
// 解析数字,直到遇到 '.' 或结束
while (index < right && version.charAt(index) != '.') {
num = num * 10 + (version.charAt(index) - '0');
index++;
}
// 跳过当前的 '.',为下一段做准备
if (index < right && version.charAt(index) == '.') {
index++;
}
hash.put(v, index);
return num;
}
}
三、BM23 二叉树的前序遍历
题目链接:BM23 二叉树的前序遍历
题目描述:

题目解析:
- 二叉树前序遍历
解题思路:
- 递归思路:根节点-左子树-右子树
- 循环思路:使用栈,先进后出,根节点-右子树-左子树
解题代码:
java
//空间复杂度:O(N)
//时间复杂度:O(N)
import java.util.*;
public class Solution {
public int[] preorderTraversal (TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
dfs(root, list);
int[] ret = new int[list.size()];
for(int i = 0; i < list.size(); i++) ret[i] = list.get(i);
return ret;
}
private void dfs(TreeNode root, ArrayList<Integer> list) {
if(root == null) return;
list.add(root.val);
dfs(root.left, list);
dfs(root.right, list);
}
}
import java.util.*;
public class Solution {
public int[] preorderTraversal (TreeNode root) {
if (root == null) return new int[]{};
ArrayList<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
list.add(cur.val);
if (cur.right != null) stack.push(cur.right);
if (cur.left != null) stack.push(cur.left);
}
int[] ret = new int[list.size()];
for (int i = 0; i < list.size(); i++) ret[i] = list.get(i);
return ret;
}
}
四、BM24 二叉树的中序遍历
题目链接:BM24 二叉树的中序遍历
题目描述:

题目解析:
- 二叉树中序遍历
解题思路:
- 递归:前-中-后递归遍历,将顺序表赋值给数组。
- 循环: 使用栈,如果节点是null,证明将该节点作为左孩子的节点可以入结果数组了,并且将右孩子入栈,不是null,就将左孩子继续入栈。
解题代码:
java
//时间复杂度:O(N)
//空间复杂度:O(N)
import java.util.*;
public class Solution {
ArrayList<Integer> list = new ArrayList<>();
public int[] inorderTraversal (TreeNode root) {
fun(root);
int len = list.size();
if(len == 0) return new int[]{};
//赋值
int[] arr = new int[len];
for(int i = 0; i < len; i++) {
arr[i] = list.get(i);
}
return arr;
}
//中序遍历
private void fun(TreeNode root) {
if(root == null) return;
fun(root.left);
list.add(root.val);
fun(root.right);
}
}
import java.util.*;
public class Solution {
public int[] inorderTraversal (TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
ArrayList<Integer> list = new ArrayList<>();
if (root == null) return new int[]{};
stack.add(root);
while (!stack.isEmpty()) {
TreeNode pop = stack.pop();
if (pop != null) {
stack.add(pop);
stack.add(pop.left);
} else if (!stack.isEmpty()) {
TreeNode pop1 = stack.pop();
list.add(pop1.val);
stack.add(pop1.right);
}
}
int[] result = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
result[i] = list.get(i);
}
return result;
}
}
五、BM25 二叉树的后序遍历
题目链接:BM25 二叉树的后序遍历
题目描述:

题目解析:
- 后序遍历
解题思路:
- 递归:前-中-后递归遍历,将顺序表赋值给数组。
- 循环: 使用栈,拿取栈顶元素,如果栈顶左子树不为空,上一个栈顶元素不是现在栈顶节点孩子,那么左子树入栈;如果右子树不为空,上一个栈顶元素不是现在栈顶节点右孩子,那么右子树入栈;都不是就出栈顶元素赋值。
解题代码:
java
//时间复杂度:O(N)
//空间复杂度:O(N)
import java.util.*;
public class Solution {
ArrayList<Integer> list = new ArrayList<>();
public int[] postorderTraversal (TreeNode root) {
fun(root);
int size = list.size();
if(size == 0) return new int[]{};
int[] arr = new int[size];
for(int i = 0; i < size; i++) {
arr[i] = list.get(i);
}
return arr;
}
private void fun(TreeNode root) {
if(root == null) return;
fun(root.left);
fun(root.right);
list.add(root.val);
}
}
import java.util.*;
public class Solution {
ArrayList<Integer> list = new ArrayList<>();
public int[] postorderTraversal (TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
if(root == null) return new int[]{};
stack.push(root);
TreeNode cur = root;
TreeNode pre = root;
while(!stack.isEmpty()) {
cur = stack.peek();
//左子树不为空,上一个栈顶元素不是现在栈顶节点孩子
if(cur.left != null
&& pre != cur.left
&& pre != cur.right) {
stack.push(cur.left);
} else if(cur.right != null && pre != cur.right) {
//右子树不为空,上一个栈顶元素不是现在栈顶节点右孩子
stack.push(cur.right);
} else {
//左右孩子节点已经遍历完成
list.add(cur.val);
pre = stack.pop();
}
}
int size = list.size();
int[] arr = new int[size];
for(int i = 0; i < size; i++) {
arr[i] = list.get(i);
}
return arr;
}
}