diff --git a/Big_data_example/rt-gmall-parent/gmall-realtime/pom.xml b/Big_data_example/rt-gmall-parent/gmall-realtime/pom.xml
index af67415..a9c7007 100644
--- a/Big_data_example/rt-gmall-parent/gmall-realtime/pom.xml
+++ b/Big_data_example/rt-gmall-parent/gmall-realtime/pom.xml
@@ -107,6 +107,13 @@
1.2.0
+
+ junit
+ junit
+ 4.13.2
+ compile
+
+
diff --git a/Big_data_example/rt-gmall-parent/gmall-realtime/src/main/java/com/atguigu/gmall/realtime/Test1.java b/Big_data_example/rt-gmall-parent/gmall-realtime/src/main/java/com/atguigu/gmall/realtime/Test1.java
new file mode 100644
index 0000000..7c95fb4
--- /dev/null
+++ b/Big_data_example/rt-gmall-parent/gmall-realtime/src/main/java/com/atguigu/gmall/realtime/Test1.java
@@ -0,0 +1,39 @@
+package com.atguigu.gmall.realtime;
+
+
+import org.junit.Test;
+
+/**
+ *@BelongsProject: rt-gmall-parent
+ *@BelongsPackage: com.atguigu.gmall.realtime
+ *@Author: markilue
+ *@CreateTime: 2023-05-06 21:14
+ *@Description: TODO
+ *@Version: 1.0
+ */
+public class Test1 {
+
+ @Test
+ public void test() {
+ String sinTable = "base_trademark";
+ String sinkPK = "id";
+ String sinkColumn = "id,tm_name";
+ String sinExtend = "";
+ checkTable(sinTable,sinkPK,sinkColumn,sinExtend);
+ }
+
+ private void checkTable(String sinkTable, String sinkPk, String sinkColumns, String sinkExtend) {
+
+ StringBuilder sql = new StringBuilder();
+ sql.append("create table if not exist " + sinkTable + "(");
+ String[] columns = sinkColumns.split(",");
+
+ for (String column : columns) {
+ sql.append(column + " String,");
+ }
+ sql.append("PRIMARY KEY (" + sinkPk + "))");
+ System.out.println(sql.toString());
+ //create table if not exist base_trademark(id String,tm_name String,PRIMARY KEY (id))
+
+ }
+}
diff --git a/Big_data_example/rt-gmall-parent/gmall-realtime/src/main/java/com/atguigu/gmall/realtime/app/func/TableProcessFunction.java b/Big_data_example/rt-gmall-parent/gmall-realtime/src/main/java/com/atguigu/gmall/realtime/app/func/TableProcessFunction.java
index 03f5a2a..f961671 100644
--- a/Big_data_example/rt-gmall-parent/gmall-realtime/src/main/java/com/atguigu/gmall/realtime/app/func/TableProcessFunction.java
+++ b/Big_data_example/rt-gmall-parent/gmall-realtime/src/main/java/com/atguigu/gmall/realtime/app/func/TableProcessFunction.java
@@ -59,7 +59,7 @@ public class TableProcessFunction extends BroadcastProcessFunction trip[1]) {
+ min = trip[1];
+ }
+ if (max < trip[2]) {
+ max = trip[2];
+ }
+ }
+
+ //通过最大值和最小值构造差分数组
+ int[] diff = new int[max - min + 1];
+
+ for (int[] trip : trips) {
+ diff[trip[1] - min] += trip[0];
+ diff[trip[2] - min] -= trip[0];//这里之所以不用+1,是因为题意是当时就下去了
+ }
+
+ if (diff[0] > capacity) {
+ return false;
+ }
+
+ //遍历diff还原当前位置
+ for (int i = 1; i < diff.length; i++) {
+ diff[i] += diff[i - 1];
+ if (diff[i] > capacity) {
+ return false;
+ }
+ }
+ return true;
+
+
+ }
}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/window/LC_76_MinWindow.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/window/LC_76_MinWindow.java
new file mode 100644
index 0000000..b0fcb9f
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/window/LC_76_MinWindow.java
@@ -0,0 +1,233 @@
+package com.markilue.leecode.hot100.interviewHot.window;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+
+/**
+ *@BelongsProject: Leecode
+ *@BelongsPackage: com.markilue.leecode.hot100.second
+ *@Author: markilue
+ *@CreateTime: 2023-04-18 11:00
+ *@Description:
+ * TODO 力扣76 最小覆盖子串:
+ * 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
+ *@Version: 1.0
+ */
+public class LC_76_MinWindow {
+
+ @Test
+ public void test() {
+ String s = "aa", t = "aa";
+ System.out.println(minWindow1(s, t));
+ }
+
+ @Test
+ public void test1() {
+ String s = "ADOBECODEBANC", t = "ABC";
+ System.out.println(minWindow2(s, t));
+ }
+
+
+ /**
+ * 滑动窗口法
+ * 维护一个需要的窗口 和一个 滑动的窗口
+ * @param s
+ * @param t
+ * @return
+ */
+ public String minWindow(String s, String t) {
+ HashMap need = new HashMap<>();
+
+ for (char c : t.toCharArray()) {
+ need.put(c, need.getOrDefault(c, 0) + 1);
+ }//记录需要的次数
+
+ HashMap window = new HashMap<>();
+
+ int left = 0;
+ int right = 0;
+ int count = 0;//记录满足要求的个数
+ int start = 0;
+ int len = Integer.MAX_VALUE;
+
+ while (right < s.length()) {
+ char c = s.charAt(right++);
+ if (need.containsKey(c)) {
+ window.put(c, window.getOrDefault(c, 0) + 1);
+ if (need.get(c).equals(window.get(c))) {
+ count++;
+ }
+ }
+
+ //是否满足要求了
+ while (count == need.size()) {
+ if (len > right - left + 1) {
+ start = left;
+ len = right - left + 1;
+ }
+ char c1 = s.charAt(left++);
+ if (need.containsKey(c1)) {
+ Integer num = window.get(c1);
+ if (num.equals(need.get(c1))) {
+
+ count--;
+ }
+ window.put(c1, window.getOrDefault(c1, 0) - 1);//增加窗口中的个数
+ }
+ }
+
+
+ }
+
+ return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len - 1);
+
+ }
+
+
+ public String minWindow1(String s, String t) {
+
+ HashMap need = new HashMap<>();
+
+ for (char c : t.toCharArray()) {
+ need.put(c, need.getOrDefault(c, 0) + 1);
+ }
+
+ HashMap window = new HashMap<>();
+
+ int left = 0;
+ int right = 0;
+ int count = 0;
+ int result = Integer.MAX_VALUE;
+ int start = 0;
+ while (right < s.length()) {
+ char c = s.charAt(right++);
+
+ if (need.containsKey(c)) {
+ window.put(c, window.getOrDefault(c, 0) + 1);
+ if (window.get(c).equals(need.get(c))) {
+ count++;
+ }
+ }
+
+ while (left < right && count == need.size()) {
+ int length = right - left;
+ if (length < result) {
+ result = length;
+ start = left;
+ }
+ char c1 = s.charAt(left++);
+ if (need.containsKey(c1)) {
+ Integer num = window.get(c1);
+ if (num.equals(need.get(c1))) {
+ count--;
+ }
+ window.put(c1, num - 1);
+
+ }
+ }
+ }
+
+ return result == Integer.MAX_VALUE ? "" : s.substring(start, start + result);
+
+ }
+
+ public String minWindow2(String s, String t) {
+
+ HashMap need = new HashMap<>();
+
+ //遍历t,获取每个字母需要的个数
+ for (int i = 0; i < t.length(); i++) {
+ char c = t.charAt(i);
+ need.put(c, need.getOrDefault(c, 0) + 1);
+ }
+
+ HashMap window = new HashMap<>();//窗口
+
+ int left = 0;
+ int right = 0;
+ int diff = need.size();
+ int minLength = Integer.MAX_VALUE;
+ int start = 0;
+
+ while (right < s.length()) {
+ char c = s.charAt(right++);
+ if (need.containsKey(c)) {
+ Integer count = window.getOrDefault(c, 0);
+ if (count.equals(need.get(c) - 1)) {
+ diff--;
+ }
+ window.put(c, count + 1);
+ }
+
+ while (diff == 0 && left < right) {
+ int curLength = right - left;//由于之前right++了,所以这里不用+1了
+ if (curLength < minLength) {
+ minLength = curLength;
+ start = left;
+ }
+ char c1 = s.charAt(left++);
+ if (need.containsKey(c1)) {
+ Integer count = window.getOrDefault(c1, 0);
+ if (count.equals(need.get(c1))) {
+ diff++;
+ }
+ window.put(c1, count - 1);
+ }
+
+ }
+ }
+
+ return minLength == Integer.MAX_VALUE ? "" : s.substring(start, start + minLength);
+
+
+ }
+
+
+ //二刷
+ public String minWindow3(String s, String t) {
+
+ HashMap need = new HashMap<>();
+
+ for (int i = 0; i < t.length(); i++) {
+ char c = t.charAt(i);
+ need.put(c, need.getOrDefault(c, 0) + 1);
+ }
+
+ HashMap window = new HashMap<>();
+
+ int left = 0;
+ int right = 0;
+ int start = 0;
+ int len = Integer.MAX_VALUE;
+ int diff = need.size();
+ while (right < s.length()) {
+ char c = s.charAt(right++);
+ if (need.containsKey(c)) {
+ window.put(c, window.getOrDefault(c, 0) + 1);
+ if (window.get(c).equals(need.get(c))) {
+ diff--;
+ }
+ }
+
+ while (diff == 0 && left < right) {
+ int cur = right - left;
+ if (cur < len) {
+ len = cur;
+ start = left;
+ }
+ char c1 = s.charAt(left++);
+ if (need.containsKey(c1)) {
+ if (window.get(c1).equals(need.get(c1))) {
+ diff++;
+ }
+ window.put(c1, window.get(c1) - 1);
+ }
+ }
+ }
+
+ return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);
+
+
+ }
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T35_76_MinWindow.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T35_76_MinWindow.java
index 3b47ef1..8faf6a0 100644
--- a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T35_76_MinWindow.java
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T35_76_MinWindow.java
@@ -181,5 +181,53 @@ public class T35_76_MinWindow {
return minLength == Integer.MAX_VALUE ? "" : s.substring(start, start + minLength);
+ }
+
+
+ //二刷
+ public String minWindow3(String s, String t) {
+
+ HashMap need = new HashMap<>();
+
+ for (int i = 0; i < t.length(); i++) {
+ char c = t.charAt(i);
+ need.put(c, need.getOrDefault(c, 0) + 1);
+ }
+
+ HashMap window = new HashMap<>();
+
+ int left = 0;
+ int right = 0;
+ int start = 0;
+ int len = Integer.MAX_VALUE;
+ int diff = need.size();
+ while (right < s.length()) {
+ char c = s.charAt(right++);
+ if (need.containsKey(c)) {
+ window.put(c, window.getOrDefault(c, 0) + 1);
+ if (window.get(c).equals(need.get(c))) {
+ diff--;
+ }
+ }
+
+ while (diff == 0 && left < right) {
+ int cur = right - left;
+ if (cur < len) {
+ len = cur;
+ start = left;
+ }
+ char c1 = s.charAt(left++);
+ if (need.containsKey(c1)) {
+ if (window.get(c1).equals(need.get(c1))) {
+ diff++;
+ }
+ window.put(c1, window.get(c1) - 1);
+ }
+ }
+ }
+
+ return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);
+
+
}
}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T42_98_IsValidBST.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T42_98_IsValidBST.java
new file mode 100644
index 0000000..8cc44fe
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T42_98_IsValidBST.java
@@ -0,0 +1,33 @@
+package com.markilue.leecode.hot100.second;
+
+import com.markilue.leecode.tree.TreeNode;
+
+/**
+ *@BelongsProject: Leecode
+ *@BelongsPackage: com.markilue.leecode.hot100.second
+ *@Author: markilue
+ *@CreateTime: 2023-05-08 10:42
+ *@Description:
+ * TODO 力扣98 验证二叉搜索树:
+ * 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
+ * 有效 二叉搜索树定义如下:
+ * 节点的左子树只包含 小于 当前节点的数。
+ * 节点的右子树只包含 大于 当前节点的数。
+ * 所有左子树和右子树自身必须也是二叉搜索树。
+ *@Version: 1.0
+ */
+public class T42_98_IsValidBST {
+
+ public boolean isValidBST(TreeNode root) {
+ return isValid(root, Long.MIN_VALUE, Long.MAX_VALUE);
+ }
+
+ public boolean isValid(TreeNode root, long leftThreshold, long rightThreshold) {
+ if (root == null) {
+ return true;
+ }
+ boolean flag = root.val > leftThreshold && root.val < rightThreshold;
+
+ return flag && isValid(root.left, leftThreshold, root.val) && isValid(root.right, root.val, rightThreshold);
+ }
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T43_101_IsSymmetric.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T43_101_IsSymmetric.java
new file mode 100644
index 0000000..3ba9387
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T43_101_IsSymmetric.java
@@ -0,0 +1,35 @@
+package com.markilue.leecode.hot100.second;
+
+import com.markilue.leecode.tree.TreeNode;
+
+/**
+ *@BelongsProject: Leecode
+ *@BelongsPackage: com.markilue.leecode.hot100.second
+ *@Author: markilue
+ *@CreateTime: 2023-05-08 10:42
+ *@Description:
+ * TODO 力扣101 对称二叉树:
+ * 给你一个二叉树的根节点 root , 检查它是否轴对称。
+ *@Version: 1.0
+ */
+public class T43_101_IsSymmetric {
+
+ public boolean isSymmetric(TreeNode root) {
+ if (root == null) {
+ return true;
+ }
+ return isSymmetric(root.left, root.right);
+ }
+
+ public boolean isSymmetric(TreeNode node1, TreeNode node2) {
+ if (node1 == null && node2 == null) {
+ return true;
+ } else if (node1 == null || node2 == null) {
+ return false;
+ } else {
+ return node1.val == node2.val && isSymmetric(node1.left, node2.right) && isSymmetric(node1.right, node2.left);
+ }
+
+ }
+
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T44_102_LevelOrder.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T44_102_LevelOrder.java
new file mode 100644
index 0000000..c40bb47
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T44_102_LevelOrder.java
@@ -0,0 +1,69 @@
+package com.markilue.leecode.hot100.second;
+
+import com.markilue.leecode.tree.TreeNode;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ *@BelongsProject: Leecode
+ *@BelongsPackage: com.markilue.leecode.hot100.second
+ *@Author: markilue
+ *@CreateTime: 2023-05-08 11:01
+ *@Description:
+ * TODO 力扣102 二叉树的层序遍历:
+ * 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
+ *@Version: 1.0
+ */
+public class T44_102_LevelOrder {
+
+ List> result = new ArrayList<>();
+
+ //dfs递归法
+ public List> levelOrder(TreeNode root) {
+ levelOrder(root, 0);
+ return result;
+ }
+
+ public void levelOrder(TreeNode node, int level) {
+ if (node == null) return;
+ if (level >= result.size()) {
+ result.add(new ArrayList<>());
+ }
+ result.get(level).add(node.val);
+ levelOrder(node.left, level + 1);
+ levelOrder(node.right, level + 1);
+ }
+
+
+ /**
+ * 队列法
+ * @param root
+ * @return
+ */
+ public List> levelOrder1(TreeNode root) {
+
+
+ LinkedList queue = new LinkedList<>();
+ ArrayList> result = new ArrayList<>();
+ if (root == null) return result;
+
+ queue.add(root);
+
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ ArrayList cur = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ TreeNode treeNode = queue.pollFirst();
+ cur.add(treeNode.val);
+ if (treeNode.left != null) queue.addLast(treeNode.left);
+ if (treeNode.right != null) queue.addLast(treeNode.right);
+ }
+ result.add(cur);
+ }
+
+ return result;
+
+ }
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T45_104_MaxDepth.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T45_104_MaxDepth.java
new file mode 100644
index 0000000..8060a77
--- /dev/null
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T45_104_MaxDepth.java
@@ -0,0 +1,34 @@
+package com.markilue.leecode.hot100.second;
+
+import com.markilue.leecode.tree.TreeNode;
+
+/**
+ *@BelongsProject: Leecode
+ *@BelongsPackage: com.markilue.leecode.hot100.second
+ *@Author: markilue
+ *@CreateTime: 2023-05-08 11:15
+ *@Description:
+ * TODO 力扣104 二叉树的最大深度:
+ * 给定一个二叉树,找出其最大深度。
+ * 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
+ * 说明: 叶子节点是指没有子节点的节点。
+ *@Version: 1.0
+ */
+public class T45_104_MaxDepth {
+
+ int max = 0;
+
+ public int maxDepth(TreeNode root) {
+ maxDepth(root, 1);
+ return max;
+ }
+
+ public void maxDepth(TreeNode root, int depth) {
+ if (root == null) {
+ return;
+ }
+ if (max < depth) max = depth;
+ maxDepth(root.left, depth + 1);
+ maxDepth(root.right, depth + 1);
+ }
+}
diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T46_105_BuildTree.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T46_105_BuildTree.java
index 5c50ef2..97c71bf 100644
--- a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T46_105_BuildTree.java
+++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T46_105_BuildTree.java
@@ -1,17 +1,28 @@
package com.markilue.leecode.hot100.second;
import com.markilue.leecode.tree.TreeNode;
+import com.markilue.leecode.tree.TreeUtils;
+import org.junit.Test;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.hot100.second
* @Author: marklue
* @CreateTime: 2023/4/16 11:15
- * @Description: TODO 力扣105 根据前序遍历和中序遍历构造树
+ * @Description:
+ * TODO 力扣105 根据前序遍历和中序遍历构造树
+ * 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
* @Version: 1.0
*/
public class T46_105_BuildTree {
+ @Test
+ public void test() {
+ int[] preorder = {3, 9, 20, 15, 7};
+ int[] inorder = {9, 3, 15, 20, 7};
+ TreeUtils.printTreeByLevel(buildTree1(preorder,inorder));
+ }
+
int index = 0;
public TreeNode buildTree(int[] preorder, int[] inorder) {
@@ -53,4 +64,55 @@ public class T46_105_BuildTree {
return -1;//没找到
}
+
+
+ public TreeNode buildTree1(int[] preorder, int[] inorder) {
+ return buildSubTree(preorder, inorder, 0, inorder.length);
+ }
+
+ public TreeNode buildSubTree(int[] preorder, int[] inorder, int inStart, int inEnd) {
+ if (inStart >= inEnd) return null;
+ TreeNode root = new TreeNode(preorder[index]);
+ int index1 = find(inorder, inStart, inEnd, preorder[index++]);
+ root.left = buildSubTree(preorder, inorder, inStart, index1);//注意这里是index1而不是index1减1,因为这里是边界的意思,和上面inorder.length对应
+ root.right = buildSubTree(preorder, inorder, index1 + 1, inEnd);
+ return root;
+ }
+
+ public int find(int[] inorder, int start, int end, int num) {
+
+ for (int i = start; i < end; i++) {
+ if (inorder[i] == num) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+
+
+
+
+ //官方最快
+ private int in = 0;
+ private int pre = 0;
+
+ public TreeNode buildTree3(int[] preorder, int[] inorder) {
+ return build(preorder, inorder, Integer.MIN_VALUE);
+ }
+
+ private TreeNode build(int[] preorder, int[] inorder, int stop) {
+ if (pre >= preorder.length)
+ return null;
+ if (inorder[in] == stop) {//合理使用stop即到了stop就到了右边界
+ in++;
+ return null;
+ }
+
+ TreeNode node = new TreeNode(preorder[pre++]);
+ node.left = build(preorder, inorder, node.val);
+ node.right = build(preorder, inorder, stop);
+ return node;
+ }
}