diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/difference/LC_1094_CarPooling.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/difference/LC_1094_CarPooling.java index ccaf8b8..ebe4f84 100644 --- a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/difference/LC_1094_CarPooling.java +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/difference/LC_1094_CarPooling.java @@ -1,5 +1,7 @@ package com.markilue.leecode.hot100.interviewHot.difference; +import org.junit.Test; + /** *@BelongsProject: Leecode *@BelongsPackage: com.markilue.leecode.hot100.interviewHot.difference @@ -15,11 +17,59 @@ package com.markilue.leecode.hot100.interviewHot.difference; */ public class LC_1094_CarPooling { + + @Test + public void test() { + int[][] trips = {{2, 1, 5}, { + 3, 5, 7 + }}; + int capacity = 4; + System.out.println(carPooling(trips, capacity)); + } + + + /** + * 差分数组:本质上就是获得每个位置的一个大小,判断是否超过capacity + * 而数组又是范围型累加,所以可以使用差分数组法 + * 速度击败99.33% 内存击败5.5% 1ms + * @param trips + * @param capacity + * @return + */ public boolean carPooling(int[][] trips, int capacity) { + //构造差分数组 + int max = Integer.MIN_VALUE; + int min = Integer.MAX_VALUE; + for (int[] trip : trips) { + if (trip[1] < min) min = trip[1]; + if (trip[2] > max) max = trip[2]; + } + //通过最大值最小值构建差分数组 + int[] diff = new int[max - min + 1]; - return false; + for (int[] trip : trips) { + diff[trip[1] - min] += trip[0]; + int end = trip[2] - min;//当前就需要减掉 + if (end < diff.length) { + diff[end] -= trip[0]; + } + } + + if (diff[0] > capacity) { + return false; + } + + //挨个遍历判断是否合适 + 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/difference/LC_1109_CorpFlightBookings.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/difference/LC_1109_CorpFlightBookings.java index 18243de..4856791 100644 --- a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/difference/LC_1109_CorpFlightBookings.java +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/difference/LC_1109_CorpFlightBookings.java @@ -19,17 +19,17 @@ import java.util.Arrays; public class LC_1109_CorpFlightBookings { @Test - public void test(){ - int[][] bookings = {{1, 2, 10}, {2, 3, 20},{2, 5, 25}}; + public void test() { + int[][] bookings = {{1, 2, 10}, {2, 3, 20}, {2, 5, 25}}; int n = 5; - System.out.println(Arrays.toString(corpFlightBookings1(bookings,n))); + System.out.println(Arrays.toString(corpFlightBookings1(bookings, n))); } @Test - public void test1(){ + public void test1() { int[][] bookings = {{1, 2, 10}, {2, 2, 15}}; int n = 2; - System.out.println(Arrays.toString(corpFlightBookings2(bookings,n))); + System.out.println(Arrays.toString(corpFlightBookings2(bookings, n))); } @@ -68,12 +68,12 @@ public class LC_1109_CorpFlightBookings { */ public int[] corpFlightBookings1(int[][] bookings, int n) { - int[] result = new int[n+1]; + int[] result = new int[n + 1]; for (int[] booking : bookings) { int start = booking[0]; int end = booking[1]; - result[start-1] += booking[2]; + result[start - 1] += booking[2]; result[end] -= booking[2]; } @@ -84,7 +84,7 @@ public class LC_1109_CorpFlightBookings { result[i] += result[i - 1]; } - return Arrays.copyOf(result,n); + return Arrays.copyOf(result, n); } @@ -103,4 +103,32 @@ public class LC_1109_CorpFlightBookings { } return nums; } + + + /** + * 二刷:差分 + * @param bookings + * @param n + * @return + */ + public int[] corpFlightBookings3(int[][] bookings, int n) { + + //构建差分数组 + int[] diff = new int[n]; + for (int[] booking : bookings) { + diff[booking[0] - 1] += booking[2]; + if (booking[1] < n) { + diff[booking[1]] -= booking[2]; + } + } + + //通过差分数组还原当前位置 + for (int i = 1; i < diff.length; i++) { + diff[i] += diff[i - 1]; + } + + return diff; + + + } } 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 cb4016c..3b47ef1 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 @@ -25,7 +25,7 @@ public class T35_76_MinWindow { @Test public void test1() { String s = "ADOBECODEBANC", t = "ABC"; - System.out.println(minWindow1(s, t)); + System.out.println(minWindow2(s, t)); } @@ -111,7 +111,7 @@ public class T35_76_MinWindow { } while (left < right && count == need.size()) { - int length = right - left ; + int length = right - left; if (length < result) { result = length; start = left; @@ -119,7 +119,7 @@ public class T35_76_MinWindow { char c1 = s.charAt(left++); if (need.containsKey(c1)) { Integer num = window.get(c1); - if (num .equals(need.get(c1)) ) { + if (num.equals(need.get(c1))) { count--; } window.put(c1, num - 1); @@ -131,4 +131,55 @@ public class T35_76_MinWindow { 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); + + + } } diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T40_94_InorderTraversal.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T40_94_InorderTraversal.java new file mode 100644 index 0000000..b5e4ab6 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T40_94_InorderTraversal.java @@ -0,0 +1,89 @@ +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-06 12:51 + *@Description: + * TODO 力扣94 二叉树的中序遍历: + * 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 + *@Version: 1.0 + */ +public class T40_94_InorderTraversal { + + //递归法 + public List inorderTraversal(TreeNode root) { + ArrayList list = new ArrayList<>(); + inorderTraversal(root, list); + return list; + } + + public void inorderTraversal(TreeNode root, List list) { + if (root == null) { + return; + } + inorderTraversal(root.left, list); + list.add(root.val); + inorderTraversal(root.right, list); + } + + + //morris遍历法 + public List inorderTraversal1(TreeNode root) { + ArrayList list = new ArrayList<>(); + + while (root != null) { + if (root.left != null) { + TreeNode left = root.left; + while (left.right != null && left.right != root) { + left = left.right; + } + //判断是怎么出来的 + if (left.right == null) { + left.right = root; + //放心将root左移 + root = root.left; + } else { + //第二次到这里了 + list.add(root.val); + root = root.right; + left.right = null; + } + } else { + list.add(root.val); + root = root.right; + } + } + + + return list; + + } + + //stack栈法 + public List inorderTraversal2(TreeNode root) { + ArrayList result = new ArrayList<>(); + LinkedList stack = new LinkedList<>(); + + while (!stack.isEmpty() || root != null) { + if (root != null) { + stack.push(root); + root = root.left; + } else { + TreeNode cur = stack.pop(); + result.add(cur.val); + root = cur.right; + } + } + + return result; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T41_96_NumTrees.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T41_96_NumTrees.java new file mode 100644 index 0000000..6c76126 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T41_96_NumTrees.java @@ -0,0 +1,35 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-06 13:18 + *@Description: + * TODO 力扣96 不同的二叉搜索树: + * 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 + *@Version: 1.0 + */ +public class T41_96_NumTrees { + + + public int numTrees(int n) { + if (n <= 2) { + return n; + } + int[] dp = new int[n + 1]; + dp[1] = 1; + dp[0] = 1; + for (int i = 2; i < dp.length; i++) { + for (int j = 0; j < i; j++) { + dp[i] += dp[j] * dp[i - j - 1]; + } + } + + return dp[n]; + + + } +} diff --git a/interview/MeiTuan/pom.xml b/interview/MeiTuan/pom.xml new file mode 100644 index 0000000..2b31228 --- /dev/null +++ b/interview/MeiTuan/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + com.markilue.interview + MeiTuan + 1.0-SNAPSHOT + + + + 8 + 8 + + + + + + junit + junit + 4.13.2 + test + + + junit + junit + 4.13.2 + compile + + + org.projectlombok + lombok + RELEASE + compile + + + + + + + + + + + \ No newline at end of file diff --git a/interview/MeiTuan/src/main/java/com/markilue/interview/Question2.java b/interview/MeiTuan/src/main/java/com/markilue/interview/Question2.java index fa408ec..cc8443b 100644 --- a/interview/MeiTuan/src/main/java/com/markilue/interview/Question2.java +++ b/interview/MeiTuan/src/main/java/com/markilue/interview/Question2.java @@ -30,9 +30,9 @@ public class Question2 { @Test public void test() { - int k=3; - int[] nums={1 ,2 ,3 ,2 ,1 ,4, 5, 1}; - sovle(k,nums); + int k = 3; + int[] nums = {1, 2, 3, 2, 1, 4, 5, 1}; + solve(k, nums); } @@ -43,15 +43,15 @@ public class Question2 { int right = 0; - int result=0; + int result = 0; HashMap map = new HashMap<>();// while (right < nums.length) { - while (right < nums.length&&map.size() <= k) { + while (right < nums.length && map.size() <= k) { if (!map.isEmpty() && map.containsKey(nums[right])) { Integer count = map.getOrDefault(nums[right], 0); - map.put(nums[right], count+1); + map.put(nums[right], count + 1); } else { map.put(nums[right], 1); } @@ -59,16 +59,16 @@ public class Question2 { right++; } - while (left<=right&&map.size() > k) { + while (left <= right && map.size() > k) { //缩小窗口 - if(right-left-1>result){ - result=right-left-1; + if (right - left - 1 > result) { + result = right - left - 1; } if (!map.isEmpty() && map.containsKey(nums[left])) { Integer count = map.getOrDefault(nums[left], 0); - map.put(nums[left], count-1); - if(count==1)map.remove(nums[left]); + map.put(nums[left], count - 1); + if (count == 1) map.remove(nums[left]); } left++; } @@ -78,4 +78,41 @@ public class Question2 { } + + + public void solve(int k, int[] nums) { + + HashMap window = new HashMap<>();//count + + int left = 0; + int right = 0; + int count = 0; + int maxLength = Integer.MIN_VALUE; + while (right < nums.length) { + + int num = nums[right++]; + if (!window.containsKey(num)) { + count++; + } + window.put(num, window.getOrDefault(num, 0) + 1); + if (count == k) { + int curLength = right - left; + if (curLength > maxLength) { + maxLength = curLength; + } + } + while (count > k && left < right) { + int num1 = nums[left++]; + int numLeft = window.getOrDefault(num1, 0) - 1; + if (numLeft == 0) { + window.remove(num1); + count--; + } + } + + + } + System.out.println(maxLength); + + } }