Qi

Cogito ergo sum

代码解析

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
package com.demo.s119;

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

/**
* 杨辉三角 II
* 给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。
*
* 在「杨辉三角」中,每个数是它左上方和右上方的数的和。
*/
public class Solution {
public List<Integer> getRow(int rowIndex) {
List<List<Integer>> C = new ArrayList<List<Integer>>();
for (int i = 0; i <= rowIndex; ++i) {
List<Integer> row = new ArrayList<Integer>();
for (int j = 0; j <= i; ++j) {
if (j == 0 || j == i) {
row.add(1);
} else {
row.add(C.get(i - 1).get(j - 1) + C.get(i - 1).get(j));
}
}
C.add(row);
}
return C.get(rowIndex);
}
}

代码解析

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
package com.demo.s118;

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

/**
* 杨辉三角
* 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
*
* 在「杨辉三角」中,每个数是它左上方和右上方的数的和。
*/
public class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ret = new ArrayList<List<Integer>>();
for (int i = 0; i < numRows; ++i) {
List<Integer> row = new ArrayList<Integer>();
for (int j = 0; j <= i; ++j) {
if (j == 0 || j == i) {
row.add(1);
} else {
row.add(ret.get(i - 1).get(j - 1) + ret.get(i - 1).get(j));
}
}
ret.add(row);
}
return ret;
}

}

代码解析

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
66
67
68
69
70
71
72
73
74
75
76
77
package com.demo.s117;

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

/**
* 填充每个节点的下一个右侧节点指针 II
* 给定一个二叉树
*
* struct Node {
* int val;
* Node *left;
* Node *right;
* Node *next;
* }
* 填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
*
* 初始状态下,所有 next 指针都被设置为 NULL。
*
*  
*
* 进阶:
*
* 你只能使用常量级额外空间。
* 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
*
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
class Node {
public int val;
public Node left;
public Node right;
public Node next;

public Node() {}

public Node(int _val) {
val = _val;
}

public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
public class Solution {
public Node connect(Node root) {
if (root == null) {
return null;
}
Queue<Node> queue = new LinkedList<Node>();
queue.offer(root);
while (!queue.isEmpty()) {
int n = queue.size();
Node last = null;
for (int i = 1; i <= n; ++i) {
Node f = queue.poll();
if (f.left != null) {
queue.offer(f.left);
}
if (f.right != null) {
queue.offer(f.right);
}
if (i != 1) {
last.next = f;
}
last = f;
}
}
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.demo.s116;

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

/**
* 填充每个节点的下一个右侧节点指针
*
*/
class Node {
public int val;
public Node left;
public Node right;
public Node next;

public Node() {}

public Node(int _val) {
val = _val;
}

public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
public class Solution {
public Node connect(Node root) {
if (root == null) {
return root;
}

// 初始化队列同时将第一层节点加入队列中,即根节点
Queue<Node> queue = new LinkedList<Node>();
queue.add(root);

// 外层的 while 循环迭代的是层数
while (!queue.isEmpty()) {

// 记录当前队列大小
int size = queue.size();

// 遍历这一层的所有节点
for (int i = 0; i < size; i++) {

// 从队首取出元素
Node node = queue.poll();

// 连接
if (i < size - 1) {
node.next = queue.peek();
}

// 拓展下一层节点
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.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
package com.demo.s115;

/**
* 不同的子序列
* 给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
*
* 字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)
*
* 题目数据保证答案符合 32 位带符号整数范围。
*
*
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/distinct-subsequences
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class Solution {
public int numDistinct(String s, String t) {
int m = s.length(), n = t.length();
if (m < n) {
return 0;
}
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i <= m; i++) {
dp[i][n] = 1;
}
for (int i = m - 1; i >= 0; i--) {
char sChar = s.charAt(i);
for (int j = n - 1; j >= 0; j--) {
char tChar = t.charAt(j);
if (sChar == tChar) {
dp[i][j] = dp[i + 1][j + 1] + dp[i + 1][j];
} else {
dp[i][j] = dp[i + 1][j];
}
}
}
return dp[0][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;
}
}
0%