feat: 添加了LeetCode96, LeetCode416, LeetCode53, LeetCode135, LeetCode219, LeetCode406, LeetCode36四个Java类,分别对应LeetCode题目中的解法;
feat: 添加了FutureRelative类,用于演示Java中的Future和CompletableFuture用法; feat: 添加了Solution1和Solution两个类,分别对应LeetCode36题目的两种解法; 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
This commit is contained in:
parent
2219024e1b
commit
61d92b60d5
64
src/main/java/cn/whaifree/interview/HS/Qz/P1.java
Normal file
64
src/main/java/cn/whaifree/interview/HS/Qz/P1.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Integer, List<Integer>> map = new HashMap<>();
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
if (!map.containsKey(nums[i])) {
|
||||
map.put(nums[i], new ArrayList<>());
|
||||
}
|
||||
List<Integer> 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;
|
||||
}
|
||||
}
|
||||
}
|
111
src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode36.java
Normal file
111
src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode36.java
Normal file
@ -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<Character> 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<Character> 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<Character> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
if (o2[0] == o1[0]) {
|
||||
return o1[1] - o2[1];
|
||||
}
|
||||
return o2[0] - o1[0];
|
||||
}
|
||||
});
|
||||
|
||||
List<int[]> list = new ArrayList<>();
|
||||
for (int[] person : people) {
|
||||
list.add(person[1], person);
|
||||
}
|
||||
|
||||
|
||||
return list.toArray(new int[list.size()][2]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
105
src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode416.java
Normal file
105
src/main/java/cn/whaifree/redo/redo_all_240924/LeetCode416.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Integer> list = new Solution().partitionLabels(s);
|
||||
System.out.println(list);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public List<Integer> partitionLabels(String s) {
|
||||
char[] charArray = s.toCharArray();
|
||||
HashMap<Character, Integer> map = new HashMap<>();
|
||||
for (int i = 0; i < charArray.length; i++) {
|
||||
map.put(charArray[i], i);
|
||||
}
|
||||
List<Integer> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
320
src/main/java/cn/whaifree/tech/NetWorkSocket/SocketDemo.java
Normal file
320
src/main/java/cn/whaifree/tech/NetWorkSocket/SocketDemo.java
Normal file
@ -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<SelectionKey> selectedKeys = selector.selectedKeys();
|
||||
// 遍历集合中的每一个事件
|
||||
Iterator<SelectionKey> 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<AsynchronousSocketChannel, Object> {
|
||||
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<Integer, ByteBuffer>() {
|
||||
|
||||
/**
|
||||
* 当读取操作成功完成时的处理逻辑
|
||||
* @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<Integer, Object>() {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
81
src/main/java/cn/whaifree/tech/thread/FutureRelative.java
Normal file
81
src/main/java/cn/whaifree/tech/thread/FutureRelative.java
Normal file
@ -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<FutureTask> futureTasks = new ArrayList<>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
FutureTask futureTask = new FutureTask<>(new Callable<Integer>() {
|
||||
@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<CompletableFuture<Integer>> completableFutures = new ArrayList<>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(new Supplier<Integer>() {
|
||||
@Override
|
||||
public Integer get() {
|
||||
return num++;
|
||||
}
|
||||
}, executorService).exceptionally(
|
||||
throwable -> {
|
||||
System.out.println("error");
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
completableFutures.add(cf);
|
||||
}
|
||||
|
||||
// CompletableFuture<Void> allOf = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]));
|
||||
|
||||
int sum = 0;
|
||||
for (CompletableFuture<Integer> cf : completableFutures) {
|
||||
try {
|
||||
sum += cf.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user