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; + } }