From 61d92b60d52cadb99d1d581951dfa0387ee5d3c8 Mon Sep 17 00:00:00 2001 From: whaifree Date: Fri, 27 Sep 2024 11:00:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BA=86LeetCode96,?= =?UTF-8?q?=20LeetCode416,=20LeetCode53,=20LeetCode135,=20LeetCode219,=20L?= =?UTF-8?q?eetCode406,=20LeetCode36=E5=9B=9B=E4=B8=AAJava=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=E5=88=86=E5=88=AB=E5=AF=B9=E5=BA=94LeetCode=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E4=B8=AD=E7=9A=84=E8=A7=A3=E6=B3=95=EF=BC=9B=20feat:?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E4=BA=86FutureRelative=E7=B1=BB=EF=BC=8C?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E6=BC=94=E7=A4=BAJava=E4=B8=AD=E7=9A=84Futur?= =?UTF-8?q?e=E5=92=8CCompletableFuture=E7=94=A8=E6=B3=95=EF=BC=9B=20feat:?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E4=BA=86Solution1=E5=92=8CSolution?= =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E7=B1=BB=EF=BC=8C=E5=88=86=E5=88=AB=E5=AF=B9?= =?UTF-8?q?=E5=BA=94LeetCode36=E9=A2=98=E7=9B=AE=E7=9A=84=E4=B8=A4?= =?UTF-8?q?=E7=A7=8D=E8=A7=A3=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Default Changelist AffinityThreadPoolTest.java FutureRelative.java LeetCode36.java LeetCode45.java LeetCode53.java LeetCode96.java LeetCode134.java LeetCode135.java LeetCode219.java LeetCode406.java LeetCode416.java LeetCode763.java LeetCode968.java LeetCode1005.java P1.java SocketDemo.java --- .../java/cn/whaifree/interview/HS/Qz/P1.java | 64 ++++ .../redo/redo_all_240924/LeetCode1005.java | 47 +++ .../redo/redo_all_240924/LeetCode134.java | 48 +++ .../redo/redo_all_240924/LeetCode135.java | 39 +++ .../redo/redo_all_240924/LeetCode219.java | 43 +++ .../redo/redo_all_240924/LeetCode36.java | 111 ++++++ .../redo/redo_all_240924/LeetCode406.java | 47 +++ .../redo/redo_all_240924/LeetCode416.java | 105 ++++++ .../redo/redo_all_240924/LeetCode45.java | 63 ++++ .../redo/redo_all_240924/LeetCode53.java | 41 +++ .../redo/redo_all_240924/LeetCode763.java | 47 +++ .../redo/redo_all_240924/LeetCode96.java | 61 ++++ .../redo/redo_all_240924/LeetCode968.java | 66 ++++ .../tech/NetWorkSocket/SocketDemo.java | 320 ++++++++++++++++++ .../tech/thread/AffinityThreadPoolTest.java | 2 + .../whaifree/tech/thread/FutureRelative.java | 81 +++++ 16 files changed, 1185 insertions(+) create mode 100644 src/main/java/cn/whaifree/interview/HS/Qz/P1.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode1005.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode134.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode135.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode219.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode36.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode406.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode416.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode45.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode53.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode763.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode96.java create mode 100644 src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode968.java create mode 100644 src/main/java/cn/whaifree/tech/NetWorkSocket/SocketDemo.java create mode 100644 src/main/java/cn/whaifree/tech/thread/FutureRelative.java diff --git a/src/main/java/cn/whaifree/interview/HS/Qz/P1.java b/src/main/java/cn/whaifree/interview/HS/Qz/P1.java new file mode 100644 index 0000000..6359fc5 --- /dev/null +++ b/src/main/java/cn/whaifree/interview/HS/Qz/P1.java @@ -0,0 +1,64 @@ +package cn.whaifree.interview.HS.Qz; + +import java.util.Scanner; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 18:56 + * @注释 + */ +public class P1 { + + public static void main(String[] args) { + // a + b = c 一只c 求 a*b 的最大值 + Scanner scanner = new Scanner(System.in); + long i = scanner.nextLong(); + long maxProduct = 0; + for (int j = 0; j <= i; j++) { + long b = i - j; + long product = b * j; + maxProduct = Math.max(product, maxProduct); + } + System.out.println(maxProduct); + } +} + +class p2{ + public static void main(String[] args) { + + Scanner in = new Scanner(System.in); + // 注意 hasNext 和 hasNextLine 的区别 + int n = in.nextInt(); + int k = in.nextInt(); + if (n <= 1) { + System.out.println(-1); + return; + } + int[] nums = new int[n]; + for (int i = 0; i < nums.length; i++) { + nums[i] = in.nextInt(); + } + + int tmp = 0; + for (int i = 1; i < nums.length; i++) { + int search = search(nums[i], nums[i - 1]); + if (search != -1) { + tmp = Math.max(search, tmp); + } + } + System.out.println(tmp); + + } + + public static int search(int a, int b) { + int tmp = Math.min(a, b); + while (tmp > 0) { + if (a % tmp == 0 && b % tmp == 0) { + return tmp; + } + tmp--; + } + return -1; + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode1005.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode1005.java new file mode 100644 index 0000000..c73d19a --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode1005.java @@ -0,0 +1,47 @@ +package cn.whaifree.redo.redo_all_240924; + +import java.util.Arrays; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/25 18:12 + * @注释 + */ +public class LeetCode1005 { + + public static void main(String[] args) { + LeetCode1005 leetCode1005 = new LeetCode1005(); + int[] nums = {2,-3,-1,5,-4}; + int k = 2; + int i = leetCode1005.new Solution().largestSumAfterKNegations(nums, k); + System.out.println(i); + } + + class Solution { + public int largestSumAfterKNegations(int[] nums, int k) { + Arrays.sort(nums); + + // 偶数 + // 奇数 + // 最小的绝对值 + int absMin = Integer.MAX_VALUE; + for (int i = 0; i < nums.length; i++) { + if (nums[i] < 0 && k > 0) { + nums[i] = -nums[i]; + k--; + } + absMin = Math.min(absMin, Math.abs(nums[i])); + } + + int sum = Arrays.stream(nums).sum(); + // 如果还有k没使用到 + // 按照绝对值排序 + if (k % 2 == 0) { + return sum; + }else { + return sum - absMin * 2; + } + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode134.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode134.java new file mode 100644 index 0000000..e6c3ef0 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode134.java @@ -0,0 +1,48 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/25 17:53 + * @注释 + */ +public class LeetCode134 { + @Test + public void test() { + int[] gas = {4,5, 1, 2, 3, }; + int[] cost = { 1,2, 3, 4, 5,}; + System.out.println(new Solution().canCompleteCircuit(gas, cost)); + } + + + class Solution { + public int canCompleteCircuit(int[] gas, int[] cost) { + int sumGas = 0; + for (int j : gas) { + sumGas += j; + } + int sumCost = 0; + for (int j : cost) { + sumCost += j; + } + if (sumCost > sumGas) { + return -1; + } + // 包能走到 + int now = 0; + int startNow = 0; + for (int i = 0; i < gas.length; i++) { + now += gas[i]; + if (now < cost[i]) { + now = 0; + startNow = i + 1; + }else { + now -= cost[i]; + } + } + return startNow; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode135.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode135.java new file mode 100644 index 0000000..817baf9 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode135.java @@ -0,0 +1,39 @@ +package cn.whaifree.redo.redo_all_240924; + +import java.util.Arrays; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 11:37 + * @注释 + */ +public class LeetCode135 { + + class Solution { + /** + * + * + * @param ratings + * @return + */ + public int candy(int[] ratings) { + + int[] distribute = new int[ratings.length]; + Arrays.fill(distribute, 1); + for (int i = 1; i < ratings.length; i++) { + if (distribute[i] > distribute[i - 1]) { + distribute[i] = distribute[i - 1] + 1; + } + } + + for (int i = ratings.length - 2; i >= 0; i++) { + if (distribute[i] > distribute[i + 1]) { + distribute[i] = Math.max(distribute[i], distribute[i + 1] + 1); + } + } + return Arrays.stream(distribute).sum(); + + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode219.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode219.java new file mode 100644 index 0000000..0bbc509 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode219.java @@ -0,0 +1,43 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 14:43 + * @注释 + */ +public class LeetCode219 { + + @Test + public void test() { + int[] nums = {1, 2, 3, 9, 8, 7, 1}; + int k = 3; + System.out.println(new Solution().containsNearbyDuplicate(nums, k)); + } + + class Solution { + public boolean containsNearbyDuplicate(int[] nums, int k) { + Map> map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + if (!map.containsKey(nums[i])) { + map.put(nums[i], new ArrayList<>()); + } + List list = map.get(nums[i]); + for (int j = 0; j < list.size(); j++) { + if (Math.abs(i - list.get(j)) <= k) { + return true; + } + } + list.add(i); + } + return false; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode36.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode36.java new file mode 100644 index 0000000..802c5c1 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode36.java @@ -0,0 +1,111 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +import java.util.HashSet; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 14:53 + * @注释 + */ +public class LeetCode36 { + + @Test + public void test() { + char[][] board = new char[][]{ + {'5', '3', '.', '.', '7', '.', '.', '.', '.'}, + {'6', '.', '.', '1', '9', '5', '.', '.', '.'}, + {'.', '9', '8', '.', '.', '.', '.', '6', '.'}, + {'8', '.', '.', '.', '6', '.', '.', '.', '3'}, + {'4', '.', '.', '8', '.', '3', '.', '.', '1'}, + {'7', '.', '.', '.', '2', '.', '.', '.', '6'}, + {'.', '6', '.', '.', '.', '.', '2', '8', '.'}, + {'.', '.', '.', '4', '1', '9', '.', '.', '5'}, + {'.', '.', '.', '.', '8', '.', '.', '7', '9'} + }; + System.out.println(new Solution().isValidSudoku(board)); + } + + class Solution1 { + public boolean isValidSudoku(char[][] board) { + //直接用数组记录每个行、列、九宫格内数字出现的次数 + int[][] row = new int[9][9]; + int[][] col = new int[9][9]; + int[][][] sub = new int[3][3][9]; + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + char c = board[i][j]; + if (c != '.') { + int numIndex = c - '0' - 1; + row[i][numIndex]++; + col[j][numIndex]++; + sub[i / 3][j / 3][numIndex]++; + if (row[i][numIndex] > 1 || col[j][numIndex] > 1 || sub[i / 3][j / 3][numIndex] > 1) { + return false; + } + } + } + } + return true; + } + } + + class Solution { + public boolean isValidSudoku(char[][] board) { + + + int length = board.length; + for (int i = 0; i < length; i++) { + HashSet set = new HashSet<>(); + for (int j = 0; j < length; j++) { + char c = board[i][j]; + if (set.contains(c)) { + return false; + } + if (c != '.') { + set.add(c); + } + } + } + + for (int i = 0; i < length; i++) { + HashSet set = new HashSet<>(); + for (int j = 0; j < length; j++) { + char c = board[j][i]; + if (set.contains(c)) { + return false; + } + if (c != '.') { + set.add(c); + } + } + } + + + for (int i = 0; i < length; i += 3) { + for (int j = 0; j < length; j += 3) { + HashSet set = new HashSet<>(); + int x = i; + int y = j; + for (int k = 0; k < 3; k++) { + for (int l = 0; l < 3; l++) { + int newX = x + k; + int newY = y + l; + char c = board[newX][newY]; + if (set.contains(c)) { + return false; + } + if (c != '.') { + set.add(c); + } + } + } + } + } + + return true; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode406.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode406.java new file mode 100644 index 0000000..7e4abc4 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode406.java @@ -0,0 +1,47 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +import java.util.*; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 12:20 + * @注释 + */ +public class LeetCode406 { + + @Test + public void test() + { + int[][] people = {{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}}; + Solution solution = new Solution(); + int[][] result = solution.reconstructQueue(people); + System.out.println(Arrays.deepToString(result)); + } + + class Solution { + public int[][] reconstructQueue(int[][] people) { + + Arrays.sort(people, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + if (o2[0] == o1[0]) { + return o1[1] - o2[1]; + } + return o2[0] - o1[0]; + } + }); + + List list = new ArrayList<>(); + for (int[] person : people) { + list.add(person[1], person); + } + + + return list.toArray(new int[list.size()][2]); + } + } + +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode416.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode416.java new file mode 100644 index 0000000..3bbf791 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode416.java @@ -0,0 +1,105 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +import java.util.Arrays; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 13:40 + * @注释 + */ +public class LeetCode416 { + + @Test + public void test() { + int[] nums = {1,2,8,5}; + System.out.println(new Solution1().canPartition(nums)); + } + + + class Solution { + /** + * + * + * @param nums + * @return + */ + public boolean canPartition(int[] nums) { + Arrays.sort(nums); + + int sum = Arrays.stream(nums).sum(); + if (sum%2==1){ + return false; + } + int target = sum / 2; + + // 背包容量 target + // 物品 nums + int[][] dp = new int[nums.length][target + 1]; + // dp[i][j] 表示从0-i任意选择,放入容量为j的背包的最大价值 + + for (int i = nums[0]; i <= target; i++) { + dp[0][i] = nums[0]; + } + + for (int i = 1; i < nums.length; i++) { + for (int j = 1; j <= target; j++) { + if (j > nums[i]) { + dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]); + }else { + dp[i][j] = dp[i - 1][j]; + } + if (dp[i][j] == target) { + return true; + } + } + } + + return dp[nums.length - 1][target] == target; + } + } + + class Solution1 { + /** + * + * + * @param nums + * @return + */ + public boolean canPartition(int[] nums) { +// Arrays.sort(nums); + + int sum = Arrays.stream(nums).sum(); + if (sum % 2 == 1) { + return false; + } + int target = sum / 2; + + // 背包容量 target + // 物品 nums + int[] dp = new int[target + 1]; + // dp[i][j] 表示从0-i任意选择,放入容量为j的背包的最大价值 + + for (int i = nums[0]; i <= target; i++) { + dp[i] = nums[0]; + } + + for (int i = 1; i < nums.length; i++) { + for (int j = target; j > 0; j--) { + if (j > nums[i]) { + dp[j] = Math.max(dp[j - nums[i]] + nums[i], dp[j]); + } + if (dp[j] == target) { + return true; + } + } + } + + return dp[target] == target; + } + } + + +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode45.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode45.java new file mode 100644 index 0000000..98d73d8 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode45.java @@ -0,0 +1,63 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/25 16:38 + * @注释 + */ +public class LeetCode45 { + + @Test + public void test() { + int[] nums = {2, 3, 1, 1, 4}; + System.out.println(new Solution().jump(nums)); + } + + class Solution { + public int jump(int[] nums) { + int curCover = 0; + int maxCover = 0; + int jump = 0; + for (int i = 0; i < nums.length; i++) { + maxCover = Math.max(i + nums[i], maxCover); + if (i == curCover) { + jump++; + curCover = maxCover; + } + if (curCover >= nums.length - 1) { + return jump; + } + } + return jump; + } + } + + class Solution1 { + public int jump(int[] nums) { + int left = 0; + int right = 0; + int jump = 0; + int minJump = Integer.MAX_VALUE; + while (left < nums.length) { + int tmpFar = left + nums[left]; + // 找到每一跳最远能覆盖到哪,贪心 + while (left <= right) { + tmpFar = Math.max(tmpFar, left + nums[right]); + left++; + } + jump++; + if (tmpFar >= nums.length - 1) { + minJump = Math.min(minJump, jump); + break; + } + right = tmpFar; + } + return minJump == Integer.MAX_VALUE ? 1 : minJump; + + } + } + +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode53.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode53.java new file mode 100644 index 0000000..9fac5b2 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode53.java @@ -0,0 +1,41 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/25 12:37 + * @注释 + */ +public class LeetCode53 { + + @Test + public void test() { + int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; + System.out.println(new Solution().maxSubArray(nums)); + } + + class Solution { + /** + * + * dp[i] 表示以i结尾的最大连续子数组的最大和 + * + * -2,1,-3,4,-1,2,1,-5,4 + * -2 1 -2 4 3 5 6 1 5 + * + * @param nums + * @return + */ + public int maxSubArray(int[] nums) { + int[] dp = new int[nums.length]; + dp[0] = nums[0]; + int nowMax = nums[0]; + for (int i = 1; i < nums.length; i++) { + dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]); + nowMax = Math.max(nowMax, dp[i]); + } + return nowMax; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode763.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode763.java new file mode 100644 index 0000000..8ea9731 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode763.java @@ -0,0 +1,47 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 12:49 + * @注释 + */ +public class LeetCode763 { + + @Test + public void test() { + String s = "ababcbacadefegdehijhklij"; + List list = new Solution().partitionLabels(s); + System.out.println(list); + } + + class Solution { + public List partitionLabels(String s) { + char[] charArray = s.toCharArray(); + HashMap map = new HashMap<>(); + for (int i = 0; i < charArray.length; i++) { + map.put(charArray[i], i); + } + List list = new ArrayList<>(); + int left = 0; + int right = 0; + int rightMax = 0; + while (right < charArray.length) { + Integer last = map.get(charArray[right]); + rightMax = Math.max(rightMax, last); // 这个区间内最远的出现范围 + if (right == last && right == rightMax) { + list.add(right - left + 1); + left = right + 1; + } + right++; + } + return list; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode96.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode96.java new file mode 100644 index 0000000..620fe92 --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode96.java @@ -0,0 +1,61 @@ +package cn.whaifree.redo.redo_all_240924; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 13:22 + * @注释 + */ +public class LeetCode96 { + + @Test + public void test() { + Solution solution = new Solution(); + int numTrees = solution.numTrees(5); + System.out.println(numTrees); + } + + class Solution { + /** + * dp[0] = 1; + * dp[1] = 1; + * dp[2] = 2; + * dp[3] = + * 左边0 * 右边2 + * 左边1 * 右边1 + * 左边2 * 右边0 + * + * dp[k] = + * i=0-k-1 + * 左边i * 右边k-i-1 + * 左边i+1 * 右边k-i-2 + * ... + * 左边0 * 右边k-1 + * + * @param n + * @return + */ + public int numTrees(int n) { + if (n == 0) { + return 0; + } + if (n == 1) { + return 1; + } + int[] dp = new int[n + 1]; + dp[0] = 1; + dp[1] = 1; + dp[2] = 2; + for (int k = 3; k < dp.length; k++) { + int sum = 0; + for (int i = 0; i < k; i++) { + sum += dp[i] * dp[k - i - 1]; + } + dp[k] = sum; + } + return dp[n]; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode968.java b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode968.java new file mode 100644 index 0000000..6240b7e --- /dev/null +++ b/src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode968.java @@ -0,0 +1,66 @@ +package cn.whaifree.redo.redo_all_240924; + +import cn.whaifree.leetCode.model.TreeNode; +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/26 13:00 + * @注释 + */ +public class LeetCode968 { + + @Test + public void test() + { + TreeNode root = TreeNode.constructTreeByArray(0,0,null,0,null,0,null,null,0); + System.out.println(new Solution().minCameraCover(root)); + } + + class Solution { + + int res = 0; + public int minCameraCover(TreeNode root) { + return anInt(root) == 3 ? res + 1 : res; + } + + /** + * + * 1 被覆盖 + * 2 有监控 + * 3 没有监控,没有被覆盖 + * + * 1 & 1 3 + * 1 | 2 1 + * 1 | 3 2 + * 2 | 3 2 + * 2 & 2 1 + * 3 & 3 2 + * + * @param root + * @return -1不装 1 装 + * + */ + public int anInt(TreeNode root) { + if (root == null) { + return 1; // 空节点表示被覆盖,上面那个节点才能表示没有被监控 + } + int left = anInt(root.left); + int right = anInt(root.right); + if (left == 1 && right == 1) { + return 3; + } + if (left == 2 && right == 2) { + return 1; + } + if (left == 3 || right == 3) { + res++; + // 子树有没被覆盖的,就需要加监控 + return 2; + } + return 1; + } + + } +} diff --git a/src/main/java/cn/whaifree/tech/NetWorkSocket/SocketDemo.java b/src/main/java/cn/whaifree/tech/NetWorkSocket/SocketDemo.java new file mode 100644 index 0000000..fac0e8b --- /dev/null +++ b/src/main/java/cn/whaifree/tech/NetWorkSocket/SocketDemo.java @@ -0,0 +1,320 @@ +package cn.whaifree.tech.NetWorkSocket; + +import java.io.*; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.util.Iterator; +import java.util.Scanner; +import java.util.Set; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/25 21:54 + * @注释 + */ +public class SocketDemo { + + +} + +class BIOSocketClient{ + /** + * 主方法,用于启动Socket客户端,连接到指定的服务器,并进行数据传输。 + * @param args 命令行参数 + */ + public static void main(String[] args) { + String serverName = "localhost"; // 服务器地址 + int port = 12130; // 服务器端口 + try(Scanner scanner = new Scanner(System.in)) // 创建扫描器用于读取用户输入 + { + System.out.println("连接到主机:" + serverName + " ,端口号:" + port); + Socket client = new java.net.Socket(serverName, port); // 创建Socket连接 + System.out.println("远程主机地址:" + client.getRemoteSocketAddress()); + + OutputStream outToServer = client.getOutputStream(); // 获取输出流 + DataOutputStream out = new DataOutputStream(outToServer); // 包装输出流以便发送UTF-8编码的字符串 + while (scanner.hasNext()) { // 循环读取用户输入 + String next = scanner.next(); + out.writeUTF("从" + client.getLocalSocketAddress() + "发送消息: " + next); // 发送消息到服务器 + if (next.equals("end")) { // 如果用户输入end,则结束循环 + break; + } + } + + InputStream inFromServer = client.getInputStream(); // 获取输入流 + DataInputStream in = new DataInputStream(inFromServer); // 包装输入流以便读取UTF-8编码的字符串 + System.out.println("服务器响应: " + in.readUTF()); // 读取并打印服务器响应 + client.close(); // 关闭Socket连接 + }catch(IOException e) + { + e.printStackTrace(); // 打印异常信息 + } + } +} + +class BIOSocketServer{ + private static ServerSocket serverSocket; // 服务器Socket + + /** + * 静态初始化块,用于创建并配置服务器Socket。 + */ + static { + try + { + serverSocket = new ServerSocket(12130); // 创建服务器Socket并绑定端口 + serverSocket.setSoTimeout(10000); // 设置Socket超时时间为10秒 + }catch(IOException e) + { + e.printStackTrace(); // 打印异常信息 + } + } + + /** + * 主方法,用于启动Socket服务器,监听客户端连接,并处理数据传输。 + * @param args 命令行参数 + */ + public static void main(String[] args) { + while(true) // 无限循环等待客户端连接 + { + try + { + System.out.println("等待远程连接,端口号为:" + serverSocket.getLocalPort() + "..."); + try (Socket server = serverSocket.accept()) { // 接受客户端连接 + System.out.println("远程主机地址:" + server.getRemoteSocketAddress()); + DataInputStream in = new DataInputStream(server.getInputStream()); // 获取输入流 + String message = in.readUTF(); // 读取客户端消息 + while (!"end".equals(message)) { // 循环读取直到客户端发送end + System.out.println("客户端发送的消息: " + message); + message = in.readUTF(); + } + DataOutputStream out = new DataOutputStream(server.getOutputStream()); // 获取输出流 + out.writeUTF("谢谢连接我:" + server.getLocalSocketAddress() + "\nGoodbye!"); // 发送响应给客户端 + } + }catch(SocketTimeoutException s) + { + System.out.println("Socket timed out!"); // 打印超时信息 + break; // 超时则退出循环 + }catch(IOException e) + { + e.printStackTrace(); // 打印异常信息 + break; // 异常则退出循环 + } + } + } +} + +class NIOServer{ + + + /** + * 主函数,用于启动服务器并监听客户端连接及处理消息 + * @param args 命令行参数 + * @throws IOException 如果发生IO异常 + */ + public static void main(String[] args) throws IOException { + // 定义服务器监听的端口号 + int port = 12140; + + // 创建服务端服务器套接字通道 + ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); + // 绑定端口号到服务器套接字 + serverSocketChannel.socket().bind(new InetSocketAddress(port)); + // 设置通道为非阻塞模式 + serverSocketChannel.configureBlocking(false); + + // 打开一个选择器 + Selector selector = Selector.open(); + // 将服务器套接字通道注册到选择器,关注接受事件 + serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); + + // 持续监听和处理连接及读取事件 + while (true) { + // 监听并处理就绪事件 + selector.select(); + + // 获取发生事件的键集合 + Set selectedKeys = selector.selectedKeys(); + // 遍历集合中的每一个事件 + Iterator iterator = selectedKeys.iterator(); + + while (iterator.hasNext()) { + // 获取当前事件 + SelectionKey key = iterator.next(); + // 移除已处理的事件 + iterator.remove(); + + // 如果有新的连接请求 + if (key.isAcceptable()) { + // 获取服务器套接字通道 + ServerSocketChannel server = (ServerSocketChannel) key.channel(); + // 接受新的客户端连接 + SocketChannel socketChannel = server.accept(); + // 设置通道为非阻塞模式 + socketChannel.configureBlocking(false); + // 将客户端通道注册到选择器,关注读取事件 + socketChannel.register(selector, SelectionKey.OP_READ); + // 输出新连接的客户端地址 + System.out.println("新客户端连接:" + socketChannel.getRemoteAddress()); + } + + // 如果有可读取的事件 + if (key.isReadable()) { + // 获取客户端套接字通道 + SocketChannel socketChannel = (SocketChannel) key.channel(); + + // 创建缓冲区以读取数据 + ByteBuffer buffer = ByteBuffer.allocate(1024); + + int read; + StringBuilder message = new StringBuilder(); + // 读取客户端发送的数据 + while ((read = socketChannel.read(buffer)) > 0) { + buffer.flip(); + byte[] bytes = new byte[buffer.remaining()]; + buffer.get(bytes); + message.append(new String(bytes)); + buffer.clear(); + } + + // 如果读取到-1,表示客户端已关闭连接 + if (read == -1) { + socketChannel.close(); + continue; + } + + // 如果接收到的消息为"end",关闭连接 + if (message.toString().equals("end")) { + socketChannel.close(); + continue; + } + + // 输出客户端发送的消息 + System.out.println("客户端发送的消息: " + message); + // 准备响应数据并写入客户端通道 + ByteBuffer response = ByteBuffer.wrap(("服务器响应: " + message).getBytes()); + socketChannel.write(response); + } + } + } + } + +} + +class AIOServer{ + // 服务器端口常量 + private static final int PORT = 12140; + + /** + * 主函数,用于启动AIO服务器 + * @param args 命令行参数 + * @throws InterruptedException 主线程睡眠时可能抛出的异常 + * @throws IOException 网络操作可能抛出的异常 + */ + public static void main(String[] args) throws InterruptedException, IOException { + // 创建并绑定异步服务器Socket通道 + AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open() + .bind(new java.net.InetSocketAddress(PORT)); + System.out.println("服务器启动在端口 " + PORT); + + // 开始监听客户端连接 + server.accept(null, new AcceptHandler(server)); + + // 做其他事情 + + // 由于AIO是非阻塞的,这里需要让主线程保持运行状态 + Thread.sleep(Long.MAX_VALUE); + } + + /** + * 处理客户端连接请求的完成事件 + */ + static class AcceptHandler implements CompletionHandler { + private final AsynchronousServerSocketChannel server; + + /** + * 构造函数,初始化服务器通道 + * @param server 服务器通道 + */ + public AcceptHandler(AsynchronousServerSocketChannel server) { + this.server = server; + } + + /** + * 当连接成功完成时的处理逻辑 + * @param client 成功连接的客户端通道 + * @param attachment 附加数据,通常用于传递状态或进行进一步处理 + */ + @Override + public void completed(AsynchronousSocketChannel client, Object attachment) { + System.out.println("客户端连接成功"); + + // 读取客户端发送的数据 + ByteBuffer buffer = ByteBuffer.allocate(1024); + client.read(buffer, buffer, new CompletionHandler() { + + /** + * 当读取操作成功完成时的处理逻辑 + * @param result 读取到的字节数 + * @param buffer 用于读取的缓冲区 + */ + @Override + public void completed(Integer result, ByteBuffer buffer) { + buffer.flip(); // 在缓冲区(Buffer)中切换读写模式 + byte[] data = new byte[buffer.remaining()]; + buffer.get(data); + String received = new String(data); + System.out.println("从客户端接收: " + received); + + buffer.clear(); + + if ("end".equals(received.trim())) { + try { + client.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + ByteBuffer response = ByteBuffer.wrap(("服务器响应: " + received).getBytes()); + client.write(response, null, new CompletionHandler() { + @Override + public void completed(Integer result, Object attachment) { + System.out.println("数据发送成功"); + } + + @Override + public void failed(Throwable exc, Object attachment) { + exc.printStackTrace(); + } + }); + } + + client.read(buffer, buffer, this); + } + + @Override + public void failed(Throwable exc, ByteBuffer attachment) { + // 处理读取失败情况,此处未定义具体行为 + } + }); + + server.accept(null, this); + } + + /** + * 当连接请求失败时的处理逻辑 + * @param exc 异常对象 + * @param attachment 附加数据 + */ + @Override + public void failed(Throwable exc, Object attachment) { + exc.printStackTrace(); + } + } + +} + diff --git a/src/main/java/cn/whaifree/tech/thread/AffinityThreadPoolTest.java b/src/main/java/cn/whaifree/tech/thread/AffinityThreadPoolTest.java index 748b8b5..61cccd5 100644 --- a/src/main/java/cn/whaifree/tech/thread/AffinityThreadPoolTest.java +++ b/src/main/java/cn/whaifree/tech/thread/AffinityThreadPoolTest.java @@ -22,6 +22,8 @@ public class AffinityThreadPoolTest { ExecutorService executorService = Executors.newFixedThreadPool(8); long l = System.currentTimeMillis(); + + synchronized (o) { for (int i = 0; i < 3; i++) { int finalI = i; diff --git a/src/main/java/cn/whaifree/tech/thread/FutureRelative.java b/src/main/java/cn/whaifree/tech/thread/FutureRelative.java new file mode 100644 index 0000000..d0ef63b --- /dev/null +++ b/src/main/java/cn/whaifree/tech/thread/FutureRelative.java @@ -0,0 +1,81 @@ +package cn.whaifree.tech.thread; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; +import java.util.function.Supplier; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/9/25 13:36 + * @注释 + */ +public class FutureRelative { + final static ExecutorService executorService = Executors.newFixedThreadPool(10, + Executors.defaultThreadFactory()); + + + + + public static void main(String[] args) { + futureTaskDemo(); + + } + + public static void futureTaskDemo() { + List futureTasks = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + FutureTask futureTask = new FutureTask<>(new Callable() { + @Override + public Integer call() throws Exception { + Thread.sleep(1000); + return 1; + } + }); + futureTasks.add(futureTask); + executorService.submit(futureTask); + } + + for (FutureTask futureTask : futureTasks) { + try { + System.out.println(futureTask.get()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } + + static volatile int num = 0; + + public static void completeFutureDemo() { + List> completableFutures = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + CompletableFuture cf = CompletableFuture.supplyAsync(new Supplier() { + @Override + public Integer get() { + return num++; + } + }, executorService).exceptionally( + throwable -> { + System.out.println("error"); + return 0; + } + ); + completableFutures.add(cf); + } + + // CompletableFuture allOf = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])); + + int sum = 0; + for (CompletableFuture cf : completableFutures) { + try { + sum += cf.get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } + + } +}