leecode更新
This commit is contained in:
parent
1e6629760f
commit
09e3ac8282
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-09 10:18
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣78题 子集:
|
||||||
|
* 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
|
||||||
|
* 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T36_Subsets {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {1, 2, 3};
|
||||||
|
System.out.println(subsets(nums));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<Integer> cur = new ArrayList<>();
|
||||||
|
List<List<Integer>> result = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<List<Integer>> subsets(int[] nums) {
|
||||||
|
backtracking(nums, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void backtracking(int[] nums, int start) {
|
||||||
|
if (nums.length == start) {
|
||||||
|
result.add(new ArrayList<>(cur));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
if(i==0){
|
||||||
|
backtracking(nums, start + 1);
|
||||||
|
}else {
|
||||||
|
cur.add(nums[start]);
|
||||||
|
backtracking(nums, start + 1);
|
||||||
|
cur.remove(cur.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-09 10:37
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣79题 单词搜索:
|
||||||
|
* 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
|
||||||
|
* 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T37_Exist {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}};
|
||||||
|
String word = "ABCCED";
|
||||||
|
System.out.println(exist(board, word));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}};
|
||||||
|
String word = "SEE";
|
||||||
|
System.out.println(exist(board, word));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
char[][] board = {{'a'}};
|
||||||
|
String word = "a";
|
||||||
|
System.out.println(exist(board, word));
|
||||||
|
}
|
||||||
|
StringBuilder cur = new StringBuilder();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:回溯:开头加for是因为需要以每一个当开头都试一下,比价麻烦
|
||||||
|
* 速度击败14.16% 内存击败57.17% 271ms
|
||||||
|
* @param board
|
||||||
|
* @param word
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean exist(char[][] board, String word) {
|
||||||
|
|
||||||
|
for (int i = 0; i < board.length; i++) {
|
||||||
|
for (int j = 0; j < board[0].length; j++) {
|
||||||
|
if(backtracking(board, word, i, j, new boolean[board.length][board[0].length])){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean backtracking(char[][] board, String word, int i, int j, boolean[][] used) {
|
||||||
|
if (cur.length() == word.length()) {
|
||||||
|
if (word.equals(cur.toString())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (i >= board.length || j >= board[0].length || i < 0 || j < 0||used[i][j]) {
|
||||||
|
//索引越界 或者 被用过
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (board[i][j] != word.charAt(cur.length())) {//只有相等才继续
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cur.append(board[i][j]);
|
||||||
|
used[i][j] = true;
|
||||||
|
for (int k = 0; k < 4; k++) {
|
||||||
|
|
||||||
|
boolean flag = false;
|
||||||
|
if (k == 0) {
|
||||||
|
flag = backtracking(board, word, i, j + 1, used);
|
||||||
|
} else if (k == 1) {
|
||||||
|
flag = backtracking(board, word, i + 1, j, used);
|
||||||
|
} else if (k == 2) {
|
||||||
|
flag = backtracking(board, word, i, j - 1, used);
|
||||||
|
} else {
|
||||||
|
flag = backtracking(board, word, i - 1, j, used);
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
used[i][j] = false;
|
||||||
|
cur.deleteCharAt(cur.length() - 1);
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方最快:使用了很多优化手段
|
||||||
|
* 不用使用cur去记录了,而是直接使用index来判断当前比对到哪里了
|
||||||
|
* 从而避免了大量的回溯;同时也不再使用for循环,而是全在if里面
|
||||||
|
* 速度击败100% 内存击败52.42% 0ms
|
||||||
|
* @param board
|
||||||
|
* @param word
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean exist1(char[][] board, String word) {
|
||||||
|
|
||||||
|
boolean[][]used = new boolean[board.length][board[0].length];
|
||||||
|
char[] chars = word.toCharArray();
|
||||||
|
// dfs优化加速:如果满足头部字符比较多,那就反转wordArray,从尾部开始dfs
|
||||||
|
int len = chars.length;
|
||||||
|
int head = 0;
|
||||||
|
|
||||||
|
//判断等于头部的多还是尾部的多
|
||||||
|
for (char[] row : board) {
|
||||||
|
for (char ch : row) {
|
||||||
|
if (ch == chars[0]) {
|
||||||
|
head++;
|
||||||
|
} else if (ch == chars[len - 1]) {
|
||||||
|
head--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//头多就交换为尾多
|
||||||
|
if (head > 0) {
|
||||||
|
// reverse
|
||||||
|
int l = 0;
|
||||||
|
int r = len - 1;
|
||||||
|
while (l < r) {
|
||||||
|
char temp = chars[r];
|
||||||
|
chars[r] = chars[l];
|
||||||
|
chars[l] = temp;
|
||||||
|
l++;
|
||||||
|
r--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < board.length; i++) {
|
||||||
|
for (int j = 0; j < board[0].length; j++) {
|
||||||
|
if (exist(i, j, 0, board, chars, used)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean exist(int i, int j, int index,char[][] board, char[] word, boolean[][]used) {
|
||||||
|
if (i == board.length || j == board[0].length || i < 0 || j < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (board[i][j] == word[index] && !used[i][j]) {
|
||||||
|
//这里传参index去避免回溯
|
||||||
|
if (++ index == word.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
used[i][j] = true;
|
||||||
|
if (exist(i, j + 1, index, board, word, used)
|
||||||
|
|| exist(i + 1, j, index, board, word, used)
|
||||||
|
|| exist(i, j - 1, index, board, word, used)
|
||||||
|
|| exist(i - 1, j, index, board, word, used)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
used[i][j] = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-10 09:57
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣84题 柱状图中最大的矩形:
|
||||||
|
* 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
|
||||||
|
* 求在该柱状图中,能够勾勒出来的矩形的最大面积。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T38_LargestRectangleArea {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] height = {2, 1, 5, 6, 2, 3};
|
||||||
|
System.out.println(largestRectangleArea(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
int[] height = {9, 0};
|
||||||
|
System.out.println(largestRectangleArea(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
int[] height = {6,7,5,2,4,5,9,3};
|
||||||
|
System.out.println(largestRectangleArea1(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:感觉和接雨水很像,只不过一个是要找总量比他少的
|
||||||
|
* 尝试使用双指针法
|
||||||
|
* 尚且有问题
|
||||||
|
* @param heights
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int largestRectangleArea(int[] heights) {
|
||||||
|
if (heights.length == 1) {
|
||||||
|
return heights[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = heights.length >> 1;
|
||||||
|
int right = left;
|
||||||
|
int leftMin = Integer.MAX_VALUE;
|
||||||
|
int rightMin = Integer.MAX_VALUE;
|
||||||
|
int maxArea = 0;
|
||||||
|
int curArea = 0;
|
||||||
|
|
||||||
|
while (left >= 0 && right < heights.length) {
|
||||||
|
leftMin = Math.min(heights[left], leftMin);
|
||||||
|
rightMin = Math.min(heights[right], rightMin);
|
||||||
|
curArea = Math.min(leftMin, rightMin) * (right - left + 1);
|
||||||
|
if (maxArea < curArea) maxArea = curArea;
|
||||||
|
if (left == 0 || heights[left] < heights[right]) {//矮的人放心左移
|
||||||
|
right++;
|
||||||
|
} else {
|
||||||
|
left--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//忽略了每个单一的情况
|
||||||
|
for (int i = 0; i < heights.length; i++) {
|
||||||
|
if (heights[i] > maxArea) maxArea = heights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxArea;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO 官方单调栈解法:具体可以看笔记
|
||||||
|
* 1)首先我们枚举某一根柱子 iii 作为高 h=heights[i]
|
||||||
|
* 2)随后我们需要进行向左右两边扩展,使得扩展到的柱子的高度均不小于 h。
|
||||||
|
* 换句话说,我们需要找到左右两侧最近的高度小于 h 的柱子,这样这两根柱子之间(不包括其本身)的所有柱子高度均不小于 h,
|
||||||
|
* 并且就是 i能够扩展到的最远范围。
|
||||||
|
* 本质上就是寻找两边单调最大的值
|
||||||
|
* 速度击败44.82% 内存击败9.7% 30ms
|
||||||
|
* TDOO 本质上就是记录以当前高为基础,最多能扩展左右到哪里,再用当前高*最多扩展
|
||||||
|
* @param heights
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int largestRectangleArea1(int[] heights) {
|
||||||
|
int n = heights.length;
|
||||||
|
int[] left = new int[n];
|
||||||
|
int[] right = new int[n];
|
||||||
|
|
||||||
|
Deque<Integer> mono_stack = new ArrayDeque<Integer>();
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) {
|
||||||
|
mono_stack.pop();
|
||||||
|
}
|
||||||
|
left[i] = (mono_stack.isEmpty() ? -1 : mono_stack.peek());
|
||||||
|
mono_stack.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mono_stack.clear();
|
||||||
|
for (int i = n - 1; i >= 0; --i) {
|
||||||
|
while (!mono_stack.isEmpty() && heights[mono_stack.peek()] >= heights[i]) {
|
||||||
|
mono_stack.pop();
|
||||||
|
}
|
||||||
|
right[i] = (mono_stack.isEmpty() ? n : mono_stack.peek());
|
||||||
|
mono_stack.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ans = 0;
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]);
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方最快,常数空间优化
|
||||||
|
* 速度击败100% 内存击败85.54% 4ms
|
||||||
|
* @param heights
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int largestRectangleArea2(int[] heights) {
|
||||||
|
int len = heights.length;
|
||||||
|
int[] index = new int[len + 1];
|
||||||
|
int[] stack = new int[len + 1];
|
||||||
|
int top = 0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
while (top > 0 && stack[top] > heights[i]) {
|
||||||
|
int height = stack[top];
|
||||||
|
while (height == stack[--top]) {
|
||||||
|
}
|
||||||
|
result = Math.max(result, height * (i - index[top]));
|
||||||
|
}
|
||||||
|
stack[++top] = heights[i];
|
||||||
|
index[top] = i + 1;
|
||||||
|
}
|
||||||
|
while (stack[top] > 0) {
|
||||||
|
int height = stack[top];
|
||||||
|
while (height == stack[--top]) {
|
||||||
|
}
|
||||||
|
result = Math.max(result, height * (len - index[top]));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-10 13:43
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣85题 最大矩形:
|
||||||
|
* 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T39_MaximalRectangle {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:当前位置能不能和其他地方连起来取决于 左一块是不是1和上1块是不是1
|
||||||
|
* TODO 官方解法 : 本质上于T38类似,可以使用单调栈解法 就是在T38的基础上再加了一个列级的for循环
|
||||||
|
* 速度击败48.24% 内存击败77.7% 16ms
|
||||||
|
* @param matrix
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maximalRectangle(char[][] matrix) {
|
||||||
|
int m = matrix.length;
|
||||||
|
if (m == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int n = matrix[0].length;
|
||||||
|
int[][] left = new int[m][n];
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
if (matrix[i][j] == '1') {
|
||||||
|
left[i][j] = (j == 0 ? 0 : left[i][j - 1]) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
for (int j = 0; j < n; j++) { // 对于每一列,使用基于柱状图的方法
|
||||||
|
int[] up = new int[m];
|
||||||
|
int[] down = new int[m];
|
||||||
|
|
||||||
|
Deque<Integer> stack = new LinkedList<Integer>();
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
while (!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]) {
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
up[i] = stack.isEmpty() ? -1 : stack.peek();
|
||||||
|
stack.push(i);
|
||||||
|
}
|
||||||
|
stack.clear();
|
||||||
|
for (int i = m - 1; i >= 0; i--) {
|
||||||
|
while (!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]) {
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
down[i] = stack.isEmpty() ? m : stack.peek();
|
||||||
|
stack.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
int height = down[i] - up[i] - 1;
|
||||||
|
int area = height * left[i][j];
|
||||||
|
ret = Math.max(ret, area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方最快:本质上与上面的一致,不知道为啥快
|
||||||
|
* 速度击败100% 内存击败55.97% 1ms
|
||||||
|
* @param matrix
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maximalRectangle1(char[][] matrix) {
|
||||||
|
int[] heights = new int[matrix[0].length];
|
||||||
|
int max = 0;
|
||||||
|
for (int i = 0; i < matrix.length; i++) {
|
||||||
|
updateHeights(heights, matrix[i]);
|
||||||
|
|
||||||
|
max = Math.max(max, largestRectangleArea(heights));
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int largestRectangleArea(int[] heights) {
|
||||||
|
int len = heights.length;
|
||||||
|
int max = 0;
|
||||||
|
int[] stack = new int[len];
|
||||||
|
int k = -1;
|
||||||
|
for (int r = 0; r < len; r++) {
|
||||||
|
while (k != -1 && heights[stack[k]] > heights[r]) {
|
||||||
|
int low = stack[k--];
|
||||||
|
int l = k == -1 ? -1 : stack[k];
|
||||||
|
max = Math.max(max, (r - 1 - l) * heights[low]);
|
||||||
|
}
|
||||||
|
stack[++k] = r;
|
||||||
|
}
|
||||||
|
while (k != -1) {
|
||||||
|
int low = stack[k--];
|
||||||
|
int l = k == -1 ? -1 : stack[k];
|
||||||
|
max = Math.max(max, (len - 1 - l) * heights[low]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateHeights(int[] heights, char[] cells) {
|
||||||
|
for (int j = 0; j < heights.length; j++) {
|
||||||
|
heights[j] = cells[j] == '0' ? 0 : heights[j] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import com.markilue.leecode.tree.TreeNode;
|
||||||
|
import com.markilue.leecode.tree.TreeUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-10 14:35
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣94题 二叉树的中序遍历:
|
||||||
|
* 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T40_inorderTraversal {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
TreeNode root = TreeUtils.structureTree(Arrays.asList(1, null, 2,null,null, 3), 0);
|
||||||
|
System.out.println(inorderTraversal1(root));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:stack栈法
|
||||||
|
* 速度击败100% 内存击败20.99% 0ms
|
||||||
|
* @param root
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<Integer> inorderTraversal(TreeNode root) {
|
||||||
|
|
||||||
|
Stack<TreeNode> stack = new Stack<>();
|
||||||
|
|
||||||
|
TreeNode cur = root;
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
|
||||||
|
while (cur != null || !stack.isEmpty()) {
|
||||||
|
if (cur != null) {
|
||||||
|
stack.push(cur);
|
||||||
|
cur = cur.left;
|
||||||
|
} else {
|
||||||
|
TreeNode node = stack.pop();
|
||||||
|
result.add(node.val);
|
||||||
|
cur = node.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* morris遍历
|
||||||
|
* 速度击败100% 内存击败21.68%
|
||||||
|
* @param root
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<Integer> inorderTraversal1(TreeNode root) {
|
||||||
|
|
||||||
|
TreeNode cur = root;
|
||||||
|
List<Integer> result = new ArrayList<>();
|
||||||
|
|
||||||
|
while (cur != null) {
|
||||||
|
if (cur.left != null) {
|
||||||
|
TreeNode left = cur.left;
|
||||||
|
|
||||||
|
//寻找他左节点的最右节点
|
||||||
|
while (left.right != null && left.right != cur) {
|
||||||
|
left = left.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断是从什么条件出来的
|
||||||
|
if (left.right == null) {
|
||||||
|
left.right = cur;
|
||||||
|
//放心将cur左移
|
||||||
|
cur = cur.left;
|
||||||
|
} else {
|
||||||
|
//第二次遍历到了,可以加入
|
||||||
|
result.add(cur.val);
|
||||||
|
cur = cur.right;
|
||||||
|
left.right = null;//防止下次再来
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//第二次遍历到了,可以加入
|
||||||
|
result.add(cur.val);
|
||||||
|
cur = cur.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-10 15:07
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣96题 不同的二叉搜索树:
|
||||||
|
* 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T41_NumTrees {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test(){
|
||||||
|
System.out.println(numTrees(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路: n等于几 就是分别代表使用1-n为根节点的情况之后
|
||||||
|
* 速度击败100% 内存击败93.62% 0ms
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int numTrees(int n) {
|
||||||
|
if (n < 3) return n;
|
||||||
|
|
||||||
|
int[] dp = new int[n + 1];
|
||||||
|
dp[0] = 1;
|
||||||
|
dp[1] = 1;
|
||||||
|
|
||||||
|
for (int i = 3; i < dp.length; i++) {
|
||||||
|
//分别以1为底-i为底之和
|
||||||
|
for (int j = 1; j <= i; j++) {
|
||||||
|
dp[i] += dp[j - 1] * dp[i - j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[n];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import com.markilue.leecode.tree.TreeNode;
|
||||||
|
import com.markilue.leecode.tree.TreeUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-10 15:20
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣98题 验证二叉搜索树:
|
||||||
|
* 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
|
||||||
|
* 有效 二叉搜索树定义如下:
|
||||||
|
* 节点的左子树只包含 小于 当前节点的数。
|
||||||
|
* 节点的右子树只包含 大于 当前节点的数。
|
||||||
|
* 所有左子树和右子树自身必须也是二叉搜索树。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T42_IsValidBST {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
// TreeNode root = TreeUtils.structureTree(Arrays.asList(5, 1, 4, null, null, 3, 6), 0);
|
||||||
|
TreeNode root = TreeUtils.structureTree(Arrays.asList(2,1,3), 0);
|
||||||
|
System.out.println(isValidBST(root));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:深度优先,从下往上确定范围
|
||||||
|
* @param root
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isValidBST(TreeNode root) {
|
||||||
|
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isValidBST(TreeNode root, long leftThreshold, long rightThreshold) {
|
||||||
|
if (root == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean left = isValidBST(root.left, leftThreshold, root.val);
|
||||||
|
if (!left) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean right = isValidBST(root.right, root.val, rightThreshold);
|
||||||
|
|
||||||
|
if (!right) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return root.val > leftThreshold && root.val < rightThreshold;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4(){
|
||||||
|
Scanner sc = new Scanner(System.in);
|
||||||
|
|
||||||
|
int count = sc.nextInt();
|
||||||
|
|
||||||
|
while(count-->0){
|
||||||
|
int a = sc.nextInt();
|
||||||
|
int b = sc.nextInt();
|
||||||
|
System.out.println(a+b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Scanner sc = new Scanner(System.in);
|
||||||
|
|
||||||
|
// int count = sc.nextInt();
|
||||||
|
String[] s = sc.nextLine().split(" ");
|
||||||
|
int[] a=new int[s.length];
|
||||||
|
|
||||||
|
int res = Arrays.stream(s).mapToInt(Integer::parseInt).sum();
|
||||||
|
|
||||||
|
System.out.println(res);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue