0%

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.demo.s1143;

import java.util.HashMap;
import java.util.Map;

/**
* 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
*
* 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
*
* 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。
* 两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/longest-common-subsequence
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int longestCommonSubsequence(String text1, String text2) {
// 新建二维数组 m n 做动态规划
int m = text1.length(), n = text2.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
char c1 = text1.charAt(i - 1);
for (int j = 1; j <= n; j++) {
char c2 = text2.charAt(j - 1);
//如果对应位置字符相同,增对应位置值 为 前一位置(i-1,j -1)值 + 1
if (c1 == c2) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
//否则取其中前面(i-1,j) 或者(i, j-1)最大的那个值
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[m][n];
}

}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.demo.s114;

import java.util.ArrayList;
import java.util.List;

/**
* 二叉树展开为链表
* 给你二叉树的根结点 root ,请你将它展开为一个单链表:
*
* 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
* 展开后的单链表应该与二叉树 先序遍历 顺序相同。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/flatten-binary-tree-to-linked-list
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/

class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public void flatten(TreeNode root) {
List<TreeNode> list = new ArrayList<TreeNode>();
preorderTraversal(root, list);
int size = list.size();
for (int i = 1; i < size; i++) {
TreeNode prev = list.get(i - 1), curr = list.get(i);
prev.left = null;
prev.right = curr;
}
}

public void preorderTraversal(TreeNode root, List<TreeNode> list) {
if (root != null) {
list.add(root);
preorderTraversal(root.left, list);
preorderTraversal(root.right, list);
}
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.demo.s113;

import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

/**
* 路径总和 II
* 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
*
* 叶子节点 是指没有子节点的节点。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/path-sum-ii
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
//定义结果list
List<List<Integer>> ret = new LinkedList<List<Integer>>();
//定义路径
Deque<Integer> path = new LinkedList<Integer>();

public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
//深度遍历
dfs(root, targetSum);
return ret;
}

public void dfs(TreeNode root, int targetSum) {
//遍历到叶子节点结束
if (root == null) {
return;
}
//把遍历路径的值存到队列中
path.offerLast(root.val);
//目标值减小
targetSum -= root.val;
//直到没有叶子节点了,或者 目标值为0 也就是 路径和 == targetSum了
if (root.left == null && root.right == null && targetSum == 0) {
//把队列的路径存到结果list中
ret.add(new LinkedList<Integer>(path));
}
//深度遍历左子树
dfs(root.left, targetSum);
//深度遍历右子树
dfs(root.right, targetSum);
//把路径中的值弹出
path.pollLast();
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.demo.s112;

import java.util.LinkedList;
import java.util.Queue;

/**
* 路径总和
* 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
*
* 叶子节点 是指没有子节点的节点。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/path-sum
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
//判空
if (root == null) {
return false;
}
//遍历树时存放节点用
Queue<TreeNode> queNode = new LinkedList<TreeNode>();
//存放当前路径值
Queue<Integer> queVal = new LinkedList<Integer>();
//从root开始遍历
queNode.offer(root);
queVal.offer(root.val);
//遍历Queue中节点
while (!queNode.isEmpty()) {
TreeNode now = queNode.poll();
int temp = queVal.poll();
//深度遍历终止条件,左右子树为null,存入的长度 == sum
if (now.left == null && now.right == null) {
if (temp == sum) {
return true;
}
continue;
}
//左子树不为null
if (now.left != null) {
queNode.offer(now.left);
queVal.offer(now.left.val + temp);
}
//右子树不为null
if (now.right != null) {
queNode.offer(now.right);
queVal.offer(now.right.val + temp);
}
}
return false;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.demo.s111;

/**
* 二叉树的最小深度
* 给定一个二叉树,找出其最小深度。
*
* 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
*
* 说明:叶子节点是指没有子节点的节点。
*/
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}

if (root.left == null && root.right == null) {
return 1;
}

int min_depth = Integer.MAX_VALUE;
if (root.left != null) {
min_depth = Math.min(minDepth(root.left), min_depth);
}
if (root.right != null) {
min_depth = Math.min(minDepth(root.right), min_depth);
}

return min_depth + 1;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.demo.s110;

/**
* 平衡二叉树
* 给定一个二叉树,判断它是否是高度平衡的二叉树。
*
* 本题中,一棵高度平衡二叉树定义为:
*
* 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
*/
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}

class Solution {
//如果等于-1就表示不是平衡的
private static final int UNBALANCED = -1;

public boolean isBalanced(TreeNode root) {
return helper(root) != UNBALANCED;
}

public int helper(TreeNode root) {
if (root == null)
return 0;

//如果左子节点不是平衡二叉树,直接返回UNBALANCED
int left = helper(root.left);
if (left == UNBALANCED)
return UNBALANCED;

//如果右子节点不是平衡二叉树,直接返回UNBALANCED
int right = helper(root.right);
if (right == UNBALANCED)
return UNBALANCED;

//如果左右子节点都是平衡二叉树,但他们的高度相差大于1,
//直接返回UNBALANCED
if (Math.abs(left - right) > 1)
return UNBALANCED;

//否则就返回二叉树中节点的最大高度
return Math.max(left, right) + 1;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.demo.s11;

/**
* 盛最多水的容器
* 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
*
* 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
*
* 返回容器可以储存的最大水量。
*
* 说明:你不能倾斜容器。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/container-with-most-water
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int maxArea(int[] height) {
int l = 0, r = height.length - 1;
int ans = 0;
while (l < r) {
int area = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, area);
if (height[l] <= height[r]) {
++l;
}
else {
--r;
}
}
return ans;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.demo.s109;

/**
* 有序链表转换二叉搜索树
* 给定一个单链表的头节点  head ,其中的元素 按升序排序 ,将其转换为高度平衡的二叉搜索树。
*
* 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差不超过 1。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/convert-sorted-list-to-binary-search-tree
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/

class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}

class Solution {
public TreeNode sortedListToBST(ListNode head) {
return buildTree(head, null);
}

public TreeNode buildTree(ListNode left, ListNode right) {
if (left == right) {
return null;
}
ListNode mid = getMedian(left, right);
TreeNode root = new TreeNode(mid.val);
root.left = buildTree(left, mid);
root.right = buildTree(mid.next, right);
return root;
}

public ListNode getMedian(ListNode left, ListNode right) {
ListNode fast = left;
ListNode slow = left;
while (fast != right && fast.next != right) {
fast = fast.next;
fast = fast.next;
slow = slow.next;
}
return slow;
}

}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.demo.s108;

/**
* 将有序数组转换为二叉搜索树
* 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
*
* 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return helper(nums, 0, nums.length - 1);
}

public TreeNode helper(int[] nums, int left, int right) {
if (left > right) {
return null;
}

// 总是选择中间位置左边的数字作为根节点
int mid = (left + right) / 2;

TreeNode root = new TreeNode(nums[mid]);
root.left = helper(nums, left, mid - 1);
root.right = helper(nums, mid + 1, right);
return root;
}
}

代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.demo.s107;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
* 二叉树的层序遍历 II
* 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
*/
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> levelOrder = new LinkedList<List<Integer>>();
if (root == null) {
return levelOrder;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> level = new ArrayList<Integer>();
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
TreeNode left = node.left, right = node.right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}
}
levelOrder.add(0, level);
}
return levelOrder;
}
}