leecode更新

This commit is contained in:
markilue 2023-05-08 12:40:58 +08:00
parent 2aaa3a3931
commit d0a8cfc1cf
12 changed files with 641 additions and 5 deletions

View File

@ -107,6 +107,13 @@
<version>1.2.0</version> <version>1.2.0</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>

View File

@ -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))
}
}

View File

@ -111,5 +111,14 @@ public class TableProcessFunction extends BroadcastProcessFunction<JSONObject, S
//处理配置数据的时候 提前建立维度表 create table if not exist 表空间.表名(字段名 数据类型) //处理配置数据的时候 提前建立维度表 create table if not exist 表空间.表名(字段名 数据类型)
private void checkTable(String sinkTable, String sinkPk, String sinkColumns, String sinkExtend) { 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 + "))");
} }
} }

View File

@ -0,0 +1,25 @@
package com.atguigu.gmall.realtime.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
*@BelongsProject: rt-gmall-parent
*@BelongsPackage: com.atguigu.gmall.realtime.utils
*@Author: markilue
*@CreateTime: 2023-05-06 20:57
*@Description: TODO 编写Phoenix工具类,执行sql
*@Version: 1.0
*/
public class MyPhoenixUtils {
private static final String URL ="jdbc:phoenix:thin:url=http://Ding202:8765;serialization=PROTOBUF";
public void executeSQL(String sql) throws SQLException {
Connection connection = DriverManager.getConnection(URL);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.execute();
}
}

View File

@ -21,7 +21,7 @@ public class LC_1094_CarPooling {
@Test @Test
public void test() { public void test() {
int[][] trips = {{2, 1, 5}, { int[][] trips = {{2, 1, 5}, {
3, 5, 7 3, 3, 7
}}; }};
int capacity = 4; int capacity = 4;
System.out.println(carPooling(trips, capacity)); System.out.println(carPooling(trips, capacity));
@ -72,4 +72,46 @@ public class LC_1094_CarPooling {
return true; return true;
} }
//二刷
public boolean carPooling1(int[][] trips, int capacity) {
//本质上就是判断某一个位置上是否超过capacity
//那么考虑把每一个位置上的数算出来
//由于不知道到底有哪些位置所以先获取最大值和最小值,构造差分数组
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int[] trip : trips) {
if (min > 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;
}
} }

View File

@ -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<Character, Integer> need = new HashMap<>();
for (char c : t.toCharArray()) {
need.put(c, need.getOrDefault(c, 0) + 1);
}//记录需要的次数
HashMap<Character, Integer> 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<Character, Integer> need = new HashMap<>();
for (char c : t.toCharArray()) {
need.put(c, need.getOrDefault(c, 0) + 1);
}
HashMap<Character, Integer> 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<Character, Integer> 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<Character, Integer> 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<Character, Integer> 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<Character, Integer> 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);
}
}

View File

@ -181,5 +181,53 @@ public class T35_76_MinWindow {
return minLength == Integer.MAX_VALUE ? "" : s.substring(start, start + minLength); return minLength == Integer.MAX_VALUE ? "" : s.substring(start, start + minLength);
}
//二刷
public String minWindow3(String s, String t) {
HashMap<Character, Integer> 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<Character, Integer> 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);
} }
} }

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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<List<Integer>> result = new ArrayList<>();
//dfs递归法
public List<List<Integer>> 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<List<Integer>> levelOrder1(TreeNode root) {
LinkedList<TreeNode> queue = new LinkedList<>();
ArrayList<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
ArrayList<Integer> 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;
}
}

View File

@ -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);
}
}

View File

@ -1,17 +1,28 @@
package com.markilue.leecode.hot100.second; package com.markilue.leecode.hot100.second;
import com.markilue.leecode.tree.TreeNode; import com.markilue.leecode.tree.TreeNode;
import com.markilue.leecode.tree.TreeUtils;
import org.junit.Test;
/** /**
* @BelongsProject: Leecode * @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.hot100.second * @BelongsPackage: com.markilue.leecode.hot100.second
* @Author: marklue * @Author: marklue
* @CreateTime: 2023/4/16 11:15 * @CreateTime: 2023/4/16 11:15
* @Description: TODO 力扣105 根据前序遍历和中序遍历构造树 * @Description:
* TODO 力扣105 根据前序遍历和中序遍历构造树
* 给定两个整数数组 preorder inorder 其中 preorder 是二叉树的先序遍历 inorder 是同一棵树的中序遍历请构造二叉树并返回其根节点
* @Version: 1.0 * @Version: 1.0
*/ */
public class T46_105_BuildTree { 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; int index = 0;
public TreeNode buildTree(int[] preorder, int[] inorder) { public TreeNode buildTree(int[] preorder, int[] inorder) {
@ -53,4 +64,55 @@ public class T46_105_BuildTree {
return -1;//没找到 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;
}
} }