redo
This commit is contained in:
parent
1044629a5e
commit
d8c1950a6b
9
pom.xml
9
pom.xml
@ -9,14 +9,19 @@
|
|||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cglib</groupId>
|
||||||
|
<artifactId>cglib</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-http</artifactId>
|
<artifactId>hutool-http</artifactId>
|
||||||
|
468
src/main/java/cn/whaifree/interview/tx/tx01.java
Normal file
468
src/main/java/cn/whaifree/interview/tx/tx01.java
Normal file
@ -0,0 +1,468 @@
|
|||||||
|
package cn.whaifree.interview.tx;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/3/31 19:55
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class tx01 {
|
||||||
|
|
||||||
|
// public volatile Integer single = null;
|
||||||
|
//
|
||||||
|
// public Integer getSingle() {
|
||||||
|
// if (single == null) {
|
||||||
|
// synchronized (Integer.class) {
|
||||||
|
// if (single == null) {
|
||||||
|
// return new Integer(1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
static class c extends Thread{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
System.out.println("c");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new c().start();
|
||||||
|
Runnable runnable = () -> {
|
||||||
|
System.out.println("1");
|
||||||
|
};
|
||||||
|
|
||||||
|
Callable<Object> objectCallable = new Callable<>() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
System.out.println("call");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FutureTask<Object> objectFutureTask = new FutureTask<>(objectCallable);
|
||||||
|
new Thread(objectFutureTask).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class p1 {
|
||||||
|
/**
|
||||||
|
* 小红拿到了一个无向图,其中一些边被染成了红色。
|
||||||
|
* 小红定义一个点是“好点”,当且仅当这个点的所有邻边都是红边。
|
||||||
|
* 现在请你求出这个无向图“好点”的数量。
|
||||||
|
* 注:如果一个节点没有任何邻边,那么它也是好点。
|
||||||
|
* <p>
|
||||||
|
* 输入描述
|
||||||
|
* 第一行输入两个正整数n,m,代表节点的数量和边的数量。
|
||||||
|
* 接下来的m行,每行输入两个正整数u,v和一个字符chr,代表节点u和节点v有一条边连接。如果 chr 为'R',代表这条边被染红;'W'代表未被染色。
|
||||||
|
* <p>
|
||||||
|
* 1\leq n,m \leq 10^5
|
||||||
|
* 1\leq u,v \leq n
|
||||||
|
* <p>
|
||||||
|
* 输出描述
|
||||||
|
* 一个整数,代表“好点”的数量。
|
||||||
|
* <p>
|
||||||
|
* 示例 1
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* 4 4
|
||||||
|
* 1 2 R
|
||||||
|
* 2 3 W
|
||||||
|
* 3 4 W
|
||||||
|
* 1 4 R
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* 1
|
||||||
|
* 说明
|
||||||
|
* 只有 1 号节点是好点。
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
int n = scanner.nextInt();
|
||||||
|
int m = scanner.nextInt();
|
||||||
|
|
||||||
|
HashMap<Integer, List<int[]>> map = new HashMap<>();
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
int a = scanner.nextInt();
|
||||||
|
int b = scanner.nextInt();
|
||||||
|
String next = scanner.next();
|
||||||
|
if (next.equals("R")) {
|
||||||
|
if (!map.containsKey(a)) {
|
||||||
|
map.put(a, new ArrayList<>());
|
||||||
|
}
|
||||||
|
map.get(a).add(new int[]{b, 1});
|
||||||
|
|
||||||
|
if (!map.containsKey(b)) {
|
||||||
|
map.put(b, new ArrayList<>());
|
||||||
|
}
|
||||||
|
map.get(b).add(new int[]{a, 1});
|
||||||
|
} else {
|
||||||
|
if (!map.containsKey(a)) {
|
||||||
|
map.put(a, new ArrayList<>());
|
||||||
|
}
|
||||||
|
map.get(a).add(new int[]{b, 0});
|
||||||
|
if (!map.containsKey(b)) {
|
||||||
|
map.put(b, new ArrayList<>());
|
||||||
|
}
|
||||||
|
map.get(b).add(new int[]{a, 0});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
Set<Integer> integers = map.keySet();
|
||||||
|
for (Integer key : integers) {
|
||||||
|
boolean flag = true;
|
||||||
|
List<int[]> ints = map.get(key);
|
||||||
|
for (int[] anInt : ints) {
|
||||||
|
if (anInt[1] == 0) {
|
||||||
|
flag = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag) res++;
|
||||||
|
}
|
||||||
|
// 对没有边的
|
||||||
|
res += (n - integers.size());
|
||||||
|
|
||||||
|
System.out.println(res);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class p2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小红拿到了一个链表。她准备将这个链表断裂成两个链表,再拼接到一起,使得链表从头节点到尾部升序。你能帮小红判断能否达成目的吗?
|
||||||
|
* 给定的为一个链表数组,你需要对于数组中每个链表进行一次“是”或者“否”的答案回答,并返回布尔数组。
|
||||||
|
* 每个链表的长度不小于 2,且每个链表中不包含两个相等的元素。所有链表的长度之和保证不超过10^5
|
||||||
|
* <p>
|
||||||
|
* 示例 1
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* [{1,2,3},{2,3,1},{3,2,1}]
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* [true,true,false]
|
||||||
|
* 说明
|
||||||
|
* 第三个链表无论怎么操作都不满足条件。
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.out.println(cansort(ListNode.listNodeFromArray(new int[]{1, 2, 3})));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean[] canSorted(ListNode[] lists) {
|
||||||
|
// write code here
|
||||||
|
boolean[] res = new boolean[lists.length];
|
||||||
|
for (int i = 0; i < lists.length; i++) {
|
||||||
|
boolean cansort = cansort(lists[i]);
|
||||||
|
res[i] = cansort;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean cansort(ListNode node) {
|
||||||
|
// 4 6 1 3 2 找到两个区间都递增
|
||||||
|
ListNode index = node;
|
||||||
|
int flag = 0;
|
||||||
|
while (index.next != null) {
|
||||||
|
if (index.val > index.next.val) {
|
||||||
|
if (index.next.next != null && index.next.next.val > index.val) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (flag == 1) return false;
|
||||||
|
flag = 1;
|
||||||
|
}
|
||||||
|
index = index.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class p4 {
|
||||||
|
/**
|
||||||
|
* 小红拿到了一个有 n 个节点的无向图,这个图初始并不是连通图。
|
||||||
|
* 现在小红想知道,添加恰好一条边使得这个图连通,有多少种不同的加边方案?
|
||||||
|
* <p>
|
||||||
|
* 输入描述
|
||||||
|
* 第一行输入两个正整数n,m,用空格隔开。
|
||||||
|
* 接下来的m行,每行输入两个正整数u,v,代表节点u和节点v之间有一条边连接。
|
||||||
|
* 1\leq n,m \leq 10^5
|
||||||
|
* 1\leq u,v \leq n
|
||||||
|
* 保证给出的图是不连通的。
|
||||||
|
* <p>
|
||||||
|
* 输出描述
|
||||||
|
* 一个整数,代表加边的方案数。
|
||||||
|
* <p>
|
||||||
|
* 示例 1
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* 4 2
|
||||||
|
* 1 2
|
||||||
|
* 3 4
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* 4
|
||||||
|
* 说明
|
||||||
|
* 添加边 (1,3) 或者 (1,4) 或者 (2,3) 或者 (2,4) 都是可以的。
|
||||||
|
* <p>
|
||||||
|
* 示例 2
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* 4 1
|
||||||
|
* 1 3
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* 0
|
||||||
|
* 说明
|
||||||
|
* 无论添加哪条边,都不可能使得该图变成连通图。
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
int n = scanner.nextInt();
|
||||||
|
int m = scanner.nextInt();
|
||||||
|
|
||||||
|
HashSet<Integer> set1 = new HashSet<>();
|
||||||
|
HashSet<Integer> set2 = new HashSet<>();
|
||||||
|
int a = scanner.nextInt();
|
||||||
|
int b = scanner.nextInt();
|
||||||
|
set1.add(a);
|
||||||
|
set1.add(b);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < m; i++) {
|
||||||
|
a = scanner.nextInt();
|
||||||
|
b = scanner.nextInt();
|
||||||
|
|
||||||
|
if ((set1.contains(a) || set1.contains(b))) {
|
||||||
|
set1.add(a);
|
||||||
|
set1.add(b);
|
||||||
|
} else {
|
||||||
|
set2.add(a);
|
||||||
|
set2.add(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(set1.size() * set2.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class p5 {
|
||||||
|
/**
|
||||||
|
* 小红拿到了一个数组,她准备将数组分割成 k 段,使得每段内部做按位异或后,再全部求和。小红希望最终这个和尽可能大,你能帮帮她吗?
|
||||||
|
* <p>
|
||||||
|
* 输入描述
|
||||||
|
* 输入包含两行。
|
||||||
|
* 第一行两个正整数 n, k , (1\leq k \leq n \leq 400),分别表示数组的长度和要分的段数。
|
||||||
|
* 第二行 n 个整数 a_i (0 \leq a_i \leq 10^9),表示数组 a 的元素。
|
||||||
|
* <p>
|
||||||
|
* 输出描述
|
||||||
|
* 输出一个正整数,表示最终的最大和。
|
||||||
|
* <p>
|
||||||
|
* 示例 1
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* 6 2
|
||||||
|
* 1 1 1 2 3 4
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* 10
|
||||||
|
* 说明
|
||||||
|
* 小红将数组分为了:
|
||||||
|
* [1, 4] 和 [5, 6] 这两个区间,得分分别为:1 \oplus 1 \oplus 1 \oplus 2 = 3 和 3 \oplus 4 = 7。总得分为 3+7=10。
|
||||||
|
* 可以证明不存在比 10 更优的分割方案。
|
||||||
|
* 注:\oplus 符号表示异或操作。
|
||||||
|
* <p>
|
||||||
|
* 示例 2
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* 5 3
|
||||||
|
* 1 0 1 1 0
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* 3
|
||||||
|
* 示例 3
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* 3 3
|
||||||
|
* 1 1 2
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* 4
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
int n = scanner.nextInt();
|
||||||
|
int k = scanner.nextInt();
|
||||||
|
int[] nums = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
nums[i] = scanner.nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int maxXorSum(int[] nums, int k) {
|
||||||
|
int n = nums.length;
|
||||||
|
int[][] prefixXor = new int[n + 1][k + 1];
|
||||||
|
int[][] dp = new int[n + 1][k + 1];
|
||||||
|
|
||||||
|
// 计算前缀异或和
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
prefixXor[i][0] = prefixXor[i - 1][0] ^ nums[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 1; j <= k; j++) {
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
prefixXor[i][j] = prefixXor[i][0];
|
||||||
|
dp[i][j] = dp[i - 1][j];
|
||||||
|
for (int x = 0; x < i; x++) {
|
||||||
|
dp[i][j] = Math.max(dp[i][j], dp[x][j - 1] + prefixXor[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[n][k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class p6 {
|
||||||
|
|
||||||
|
static int res = 0;
|
||||||
|
static List<Character> path = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小红拿到了一个字符矩阵,她可以从任意一个地方出发,希望走 6 步后恰好形成"tencent"字符串。小红想知道,共有多少种不同的行走方案?
|
||||||
|
* 注:每一步可以选择上、下、左、右中任意一个方向进行行走。不可行走到矩阵外部。
|
||||||
|
* <p>
|
||||||
|
* 输入描述
|
||||||
|
* 第一行输入两个正整数n,m,代表矩阵的行数和列数。
|
||||||
|
* 接下来的n行,每行输入一个长度为m的、仅由小写字母组成的字符串,代表小红拿到的矩阵。
|
||||||
|
* <p>
|
||||||
|
* 1\leq n,m \leq 1000
|
||||||
|
* <p>
|
||||||
|
* 输出描述
|
||||||
|
* 一个整数,代表最终合法的方案数。
|
||||||
|
* <p>
|
||||||
|
* 示例 1
|
||||||
|
* 收起
|
||||||
|
* <p>
|
||||||
|
* 输入
|
||||||
|
* 复制
|
||||||
|
* 3 3
|
||||||
|
* ten
|
||||||
|
* nec
|
||||||
|
* ten
|
||||||
|
* 输出
|
||||||
|
* 复制
|
||||||
|
* 4
|
||||||
|
* 说明
|
||||||
|
* 第一个方案,从左上角出发,右右下左左上。
|
||||||
|
* 第二个方案,从左上角出发,右右下左左下。
|
||||||
|
* 第三个方案,从左下角出发,右右上左左下。
|
||||||
|
* 第四个方案,从左上角出发,右右上左左上。
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
path = new ArrayList<>();
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
int n = scanner.nextInt();
|
||||||
|
int m = scanner.nextInt();
|
||||||
|
char[][] chars = new char[n][m];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
char[] c = scanner.next().toCharArray();
|
||||||
|
for (int j = 0; j < c.length; j++) {
|
||||||
|
chars[i][j] = c[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 0; j < m; j++) {
|
||||||
|
if (chars[i][j] == 't') {
|
||||||
|
path.add('t');
|
||||||
|
backing(chars, i, j);
|
||||||
|
path.remove(path.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(res);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void backing(char[][] chars, int x, int y) {
|
||||||
|
if (path.size() == 7) {
|
||||||
|
// System.out.println(new ArrayList<>(path));
|
||||||
|
res++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Character expect = null;
|
||||||
|
if (path.size() == 1) {
|
||||||
|
expect = 'e';
|
||||||
|
} else if (path.size() == 2) {
|
||||||
|
expect = 'n';
|
||||||
|
} else if (path.size() == 3) {
|
||||||
|
expect = 'c';
|
||||||
|
} else if (path.size() == 4) {
|
||||||
|
expect = 'e';
|
||||||
|
} else if (path.size() == 5) {
|
||||||
|
expect = 'n';
|
||||||
|
} else if (path.size() == 6) {
|
||||||
|
expect = 't';
|
||||||
|
}
|
||||||
|
|
||||||
|
path.add(chars[x][y]);
|
||||||
|
if (x < chars.length - 1 && expect.equals(chars[x + 1][y])) {
|
||||||
|
backing(chars, x + 1, y);
|
||||||
|
}
|
||||||
|
if (y < chars[0].length - 1 && expect.equals(chars[x][y + 1])) {
|
||||||
|
backing(chars, x, y + 1);
|
||||||
|
}
|
||||||
|
if (x > 0 && expect.equals(chars[x - 1][y])) {
|
||||||
|
backing(chars, x - 1, y);
|
||||||
|
}
|
||||||
|
if (y > 0 && expect.equals(chars[x][y - 1])) {
|
||||||
|
backing(chars, x, y - 1);
|
||||||
|
}
|
||||||
|
path.remove(path.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode121.java
Normal file
88
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode121.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package cn.whaifree.leetCode.Dynamic;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/3 14:38
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode121 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test()
|
||||||
|
{
|
||||||
|
|
||||||
|
int[] prices = {7,1,5,3,6,4};
|
||||||
|
System.out.println(new Solution1().maxProfit(prices));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。
|
||||||
|
*
|
||||||
|
* dp[i][1]表示i天不持有股票的持有现金
|
||||||
|
* dp[i][0]表示i天持有股票所有的现金
|
||||||
|
* 第i天买入股票现金就是 -prices[i]
|
||||||
|
*
|
||||||
|
* 第i天有股票 1. 刚刚买入、2. 第i-1天就有
|
||||||
|
* 第i天没有股票 2. 第i天卖出 2. 第i-1天就没有股票
|
||||||
|
*
|
||||||
|
* dp[i][0] 持有股票
|
||||||
|
* - i-1就持有股票,今天不卖 dp[i-1][0]
|
||||||
|
* - 买入股票 -今天的股价 -prices[i]
|
||||||
|
* - max
|
||||||
|
* dp[i][1] 无持有
|
||||||
|
* - i-1 保持现状dp[i-1][1]
|
||||||
|
* - 卖出 prices[i] + dp[i-1][0] 价格+[i-1]天加持有的现金
|
||||||
|
* - max
|
||||||
|
* dp[0][0] = -price[0]
|
||||||
|
* dp[0][1] = 0
|
||||||
|
*
|
||||||
|
* @param prices
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maxProfit(int[] prices) {
|
||||||
|
|
||||||
|
if (prices.length == 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] dp = new int[2];
|
||||||
|
|
||||||
|
dp[0] = -prices[0];
|
||||||
|
dp[1] = 0;
|
||||||
|
for (int i = 0; i < prices.length; i++) {
|
||||||
|
// 持有股票 1. i-1就有 2. 刚刚买入
|
||||||
|
dp[0] = Math.max(dp[0], -prices[i]);
|
||||||
|
// 无股票 2. i-1就无,2 刚刚卖出
|
||||||
|
dp[1] = Math.max(dp[1], dp[0] + prices[i]);
|
||||||
|
}
|
||||||
|
return dp[1]; // 最后一天一定没有股票才能有最大利润
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Solution1 {
|
||||||
|
/**
|
||||||
|
* 贪心
|
||||||
|
* @param prices
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maxProfit(int[] prices) {
|
||||||
|
|
||||||
|
int min = Integer.MAX_VALUE;
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; i < prices.length; i++) {
|
||||||
|
min = Math.min(min, prices[i]);
|
||||||
|
res = Math.max(res, prices[i] - min);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
40
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode198.java
Normal file
40
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode198.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package cn.whaifree.leetCode.Dynamic;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/3 13:50
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode198 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test()
|
||||||
|
{
|
||||||
|
Solution solution = new Solution();
|
||||||
|
int[] nums = new int[]{2,7};
|
||||||
|
int rob = solution.rob(nums);
|
||||||
|
System.out.println(rob);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public int rob(int[] nums) {
|
||||||
|
if (nums.length == 1) {
|
||||||
|
return nums[0];
|
||||||
|
}
|
||||||
|
// dp[i] 表示 从0-i偷窃都最大价值
|
||||||
|
// dp[i] = max(dp[i-1],dp[i-2]+nums[i]])
|
||||||
|
int[] dp = new int[nums.length];
|
||||||
|
dp[0] = nums[0];
|
||||||
|
dp[1] = Math.max(nums[0], nums[1]);
|
||||||
|
for (int i = 2; i < nums.length; i++) {
|
||||||
|
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
|
||||||
|
}
|
||||||
|
return dp[nums.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -13,9 +13,9 @@ import java.util.Arrays;
|
|||||||
public class LeetCode322 {
|
public class LeetCode322 {
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
int[] coins = {1,2,5};
|
int[] coins = {1};
|
||||||
int amount = 11;
|
int amount = 0;
|
||||||
int i = new Solution().coinChange(coins, amount);
|
int i = new Solution1().coinChange(coins, amount);
|
||||||
System.out.println(i);
|
System.out.println(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,4 +44,49 @@ public class LeetCode322 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution1 {
|
||||||
|
/**
|
||||||
|
* 背包容量为amount
|
||||||
|
* coins里随便取
|
||||||
|
*
|
||||||
|
* dp[j] 表示使用[0-i]任意硬币取凑出j的最小硬币数
|
||||||
|
*
|
||||||
|
* [1, 2, 5]
|
||||||
|
* 0 1 2 3 4 5 6
|
||||||
|
* 0 0 1 2 3 4 5 6
|
||||||
|
* 1 0 1 1 2 2 3 3
|
||||||
|
* 2
|
||||||
|
* 3
|
||||||
|
* 4
|
||||||
|
*
|
||||||
|
* dp[j] = math.min(dp[j],dp[j-coin[i]]+1)
|
||||||
|
*
|
||||||
|
* @param coins
|
||||||
|
* @param amount
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int coinChange(int[] coins, int amount) {
|
||||||
|
|
||||||
|
|
||||||
|
int[] dp = new int[amount+1];
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < dp.length; i++) {
|
||||||
|
dp[i] = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dp[0] = 0;
|
||||||
|
for (int i = 0; i < coins.length; i++) {
|
||||||
|
for (int j = coins[i]; j < amount + 1; j++) {
|
||||||
|
if (dp[j - coins[i]] != Integer.MAX_VALUE) {
|
||||||
|
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
71
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode337.java
Normal file
71
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode337.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package cn.whaifree.leetCode.Dynamic;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.TreeNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/3 13:55
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode337 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test()
|
||||||
|
{
|
||||||
|
System.out.println(new Solution().rob(TreeNode.constructTreeByArray(4,1,null,2,null,3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public int rob(TreeNode root) {
|
||||||
|
/**
|
||||||
|
* dp[0]表示不选该点的最大收益 dp[1]表示选该节点的最大收益
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int[] ints = robDown(root);
|
||||||
|
return Math.max(ints[0], ints[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] robDown(TreeNode root) {
|
||||||
|
int res[] = new int[2];
|
||||||
|
if (root == null) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int[] left = robDown(root.left);
|
||||||
|
int[] right = robDown(root.right);
|
||||||
|
|
||||||
|
// 不偷:Max(左孩子不偷,左孩子偷) + Max(右孩子不偷,右孩子偷)
|
||||||
|
// 不偷:左右随意,选最大的
|
||||||
|
res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
|
||||||
|
// 偷:左孩子不偷+ 右孩子不偷 + 当前节点偷
|
||||||
|
// 偷:必须保证左右都不偷
|
||||||
|
res[1] = left[0] + right[0] + root.val;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution1 {
|
||||||
|
public int rob(TreeNode root) {
|
||||||
|
// 两层,根节点用和不用
|
||||||
|
return Math.max(robDown(root, true), robDown(root, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int robDown(TreeNode root, boolean flag) {
|
||||||
|
if (root == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = robDown(root.left, !flag);
|
||||||
|
int right = robDown(root.right, !flag);
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
return left + right + root.val;
|
||||||
|
}else {
|
||||||
|
return left + right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -98,4 +98,7 @@ public class LeetCode377 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package cn.whaifree.leetCode.Hash;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. 两数之和
|
* 1. 两数之和
|
||||||
@ -39,7 +39,7 @@ import java.util.HashSet;
|
|||||||
*
|
*
|
||||||
* 进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
|
* 进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
|
||||||
*/
|
*/
|
||||||
public class LeetCode1 {
|
public class LeetCode1 implements Serializable {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
51
src/main/java/cn/whaifree/leetCode/LeetCode/LeetCode11.java
Normal file
51
src/main/java/cn/whaifree/leetCode/LeetCode/LeetCode11.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package cn.whaifree.leetCode.LeetCode;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/3 17:35
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode11 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
Solution solution = new Solution();
|
||||||
|
int[] height = {1,1};
|
||||||
|
int i = solution.maxArea(height);
|
||||||
|
System.out.println(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
/**
|
||||||
|
* $S(i,j)=min(h[i],h[j])*(j-i)$
|
||||||
|
* 双指针
|
||||||
|
* 长板移动面积不变或 变小
|
||||||
|
* 短板移动 变大 或不变
|
||||||
|
* 不断移动短板
|
||||||
|
* @param height
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int maxArea(int[] height) {
|
||||||
|
|
||||||
|
int storage = 0;
|
||||||
|
int left = 0;
|
||||||
|
int right = height.length - 1;
|
||||||
|
while (left < right) {
|
||||||
|
storage = Math.max(getArea(height, left, right), storage);
|
||||||
|
if (height[left] < height[right]) {
|
||||||
|
left++;
|
||||||
|
}else {
|
||||||
|
right--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getArea(int[] height, int start, int end) {
|
||||||
|
return Math.min(height[start], height[end]) * (end - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
115
src/main/java/cn/whaifree/leetCode/LeetCode/LeetCode22.java
Normal file
115
src/main/java/cn/whaifree/leetCode/LeetCode/LeetCode22.java
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package cn.whaifree.leetCode.LeetCode;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/4 13:44
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode22 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
List<String> res =new Solution1().generateParenthesis(3);
|
||||||
|
System.out.println(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
List<String> res = new ArrayList<>();
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> generateParenthesis(int n) {
|
||||||
|
backTracking(n, 0, 0);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @param leftCount 左括号用了几个
|
||||||
|
* @param rightCount 右括号用了几个
|
||||||
|
*/
|
||||||
|
public void backTracking(int n, int leftCount , int rightCount) {
|
||||||
|
|
||||||
|
if (leftCount > n || rightCount > leftCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.length() == n * 2) {
|
||||||
|
res.add(path.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
path.append("(");
|
||||||
|
backTracking(n, leftCount + 1, rightCount);
|
||||||
|
path.deleteCharAt(path.length() - 1); // 回溯
|
||||||
|
|
||||||
|
path.append(")");
|
||||||
|
backTracking(n, leftCount, rightCount + 1);
|
||||||
|
path.deleteCharAt(path.length() - 1); // 回溯
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution1 {
|
||||||
|
List<String> res = new ArrayList<>();
|
||||||
|
StringBuilder path = new StringBuilder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> generateParenthesis(int n) {
|
||||||
|
backTracking(n, n, n);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @param leftCount 左括号可用数
|
||||||
|
* @param rightCount 右括号可用数
|
||||||
|
*/
|
||||||
|
public void backTracking(int n, int leftCount , int rightCount) {
|
||||||
|
|
||||||
|
if (leftCount == 0 && rightCount == 0) {
|
||||||
|
res.add(path.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftCount > rightCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (leftCount > 0) {
|
||||||
|
path.append("(");
|
||||||
|
backTracking(n, leftCount - 1, rightCount);
|
||||||
|
path.deleteCharAt(path.length() - 1);
|
||||||
|
}
|
||||||
|
if (rightCount > 0) {
|
||||||
|
path.append(")");
|
||||||
|
backTracking(n, leftCount, rightCount - 1);
|
||||||
|
path.deleteCharAt(path.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package cn.whaifree.leetCode.LinkedList;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/4 13:05
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class LeetCode21 {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
new Solution1().mergeTwoLists(
|
||||||
|
ListNode.listNodeFromArray(new int[]{5}),
|
||||||
|
ListNode.listNodeFromArray(new int[]{1, 2, 4})
|
||||||
|
).printList();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
|
||||||
|
if (list2 == null) {
|
||||||
|
return list1;
|
||||||
|
}
|
||||||
|
if (list1 == null) {
|
||||||
|
return list2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode pre = new ListNode(-1); // 标记结果头部
|
||||||
|
ListNode preIndex = pre; // 标记需要添加的位置
|
||||||
|
// 合并有序链表
|
||||||
|
ListNode indexA = list1;
|
||||||
|
ListNode indexB = list2;
|
||||||
|
while (indexA != null && indexB != null) {
|
||||||
|
if (indexA.val <= indexB.val) {
|
||||||
|
preIndex.next = indexA;
|
||||||
|
indexA = indexA.next;
|
||||||
|
}else {
|
||||||
|
preIndex.next = indexB;
|
||||||
|
indexB = indexB.next;
|
||||||
|
}
|
||||||
|
preIndex = preIndex.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexA == null) {
|
||||||
|
preIndex.next = indexB;
|
||||||
|
}else {
|
||||||
|
preIndex.next = indexA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pre.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Solution1 {
|
||||||
|
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
|
||||||
|
|
||||||
|
if (list1 == null) {
|
||||||
|
return list2;
|
||||||
|
}
|
||||||
|
if (list2 == null) {
|
||||||
|
return list1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list1.val < list2.val) {
|
||||||
|
list1.next = mergeTwoLists(list1.next, list2);
|
||||||
|
return list1;
|
||||||
|
}else {
|
||||||
|
list2.next = mergeTwoLists(list1, list2.next);
|
||||||
|
return list2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
150
src/main/java/cn/whaifree/test/CRC16_ARC.java
Normal file
150
src/main/java/cn/whaifree/test/CRC16_ARC.java
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
package cn.whaifree.test;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/3/23 20:36
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class CRC16_ARC {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final int CRC16_ARC = 0x8005; // CRC16-ARC多项式
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算CRC16ARC校验值
|
||||||
|
* @param data 要计算校验值的数据数组
|
||||||
|
* @return 返回计算得到的CRC16ARC校验值
|
||||||
|
*/
|
||||||
|
public static int calculateCRC16ARC(byte[] data) {
|
||||||
|
// 使用CRC32算法计算校验值,然后将其转换为16位
|
||||||
|
int crcValue = 0xFFFF; // 初始值为0xFFFF,表示CRC16-ARC的初始寄存器状态
|
||||||
|
|
||||||
|
// 遍历数据数组,逐字节计算CRC校验值
|
||||||
|
for (byte b : data) {
|
||||||
|
crcValue ^= b & 0xFF; // 将数据字节与CRC值异或
|
||||||
|
|
||||||
|
// 对CRC值进行8次位运算,模拟移位和异或过程
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if ((crcValue & 0x0001) != 0) {
|
||||||
|
crcValue = (crcValue >> 1) ^ CRC16_ARC; // 如果最低位为1,进行异或运算
|
||||||
|
} else {
|
||||||
|
crcValue >>= 1; // 如果最低位为0,仅右移一位
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return crcValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为指定的源文件附加CRC16ARC校验值,并将结果保存为新文件。
|
||||||
|
*
|
||||||
|
* @param sourceFilePath 源文件路径,将对此文件进行读取。
|
||||||
|
* @param destinationFilePath 保存带有CRC校验值的新文件的路径。
|
||||||
|
* @throws IOException 如果在读取源文件或写入新文件过程中发生I/O错误。
|
||||||
|
*/
|
||||||
|
public static void attachCRC16ARC(String sourceFilePath, String destinationFilePath) throws IOException {
|
||||||
|
// 打开源文件并读取所有内容
|
||||||
|
FileInputStream fis = new FileInputStream(sourceFilePath);
|
||||||
|
byte[] data = fis.readAllBytes();
|
||||||
|
fis.close();
|
||||||
|
|
||||||
|
// 计算源文件数据的CRC16ARC校验值
|
||||||
|
int crcValue = calculateCRC16ARC(data);
|
||||||
|
|
||||||
|
// 打开目标文件,写入源文件数据和CRC校验值
|
||||||
|
FileOutputStream fos = new FileOutputStream(destinationFilePath);
|
||||||
|
fos.write(data);
|
||||||
|
// 写入CRC的高字节
|
||||||
|
fos.write((crcValue & 0xFF00) >> 8);
|
||||||
|
// 写入CRC的低字节
|
||||||
|
fos.write(crcValue & 0xFF);
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] generateCRC16ARCForSend(String filePath) throws IOException {
|
||||||
|
FileInputStream fis = new FileInputStream(filePath);
|
||||||
|
byte[] data = fis.readAllBytes();
|
||||||
|
fis.close();
|
||||||
|
|
||||||
|
// 计算CRC16ARC校验值
|
||||||
|
int crcValue = calculateCRC16ARC(data);
|
||||||
|
|
||||||
|
byte[] crcBytes = new byte[2];
|
||||||
|
crcBytes[0] = (byte) ((crcValue >> 8) & 0xFF); // 高位字节
|
||||||
|
crcBytes[1] = (byte) (crcValue & 0xFF); // 低位字节
|
||||||
|
|
||||||
|
byte[] dataWithCRC = new byte[data.length + 2];
|
||||||
|
System.arraycopy(data, 0, dataWithCRC, 0, data.length);
|
||||||
|
System.arraycopy(crcBytes, 0, dataWithCRC, data.length, 2);
|
||||||
|
|
||||||
|
return dataWithCRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean verifyCRC16ARCByBytes(byte[] bytes) {
|
||||||
|
|
||||||
|
int crcValue = ((bytes[bytes.length - 2] & 0xFF) << 8) | (bytes[bytes.length - 1] & 0xFF);
|
||||||
|
byte[] crcData = new byte[]{(byte) (crcValue >> 8), (byte) crcValue};
|
||||||
|
byte[] data = Arrays.copyOf(bytes, bytes.length - crcData.length);
|
||||||
|
int calculatedCRC = calculateCRC16ARC(data);
|
||||||
|
return crcValue == calculatedCRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件时,提取末尾的CRC值并进行验证:
|
||||||
|
* @param filePath
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static boolean verifyCRC16ARC(String filePath) throws IOException {
|
||||||
|
FileInputStream fis = new FileInputStream(filePath);
|
||||||
|
byte[] data = fis.readAllBytes();
|
||||||
|
fis.close();
|
||||||
|
|
||||||
|
// 文件附带的CRC
|
||||||
|
int fileCRC = ((data[data.length - 2] & 0xFF) << 8) | (data[data.length - 1] & 0xFF);
|
||||||
|
byte[] fileData = Arrays.copyOf(data, data.length - 2);
|
||||||
|
// 重新计算的CRC
|
||||||
|
int calculatedCRC = calculateCRC16ARC(fileData);
|
||||||
|
|
||||||
|
return fileCRC == calculatedCRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String filePath = "D:\\Downloads\\BFD-D42401883.pdf";
|
||||||
|
String destinationFilePath = "D:\\Downloads\\BFD-D42401883-1.pdf"; // 输出的
|
||||||
|
attachCRC16ARC(filePath, destinationFilePath);
|
||||||
|
if (verifyCRC16ARC(destinationFilePath)) {
|
||||||
|
System.out.println("验证成功");
|
||||||
|
}else {
|
||||||
|
System.out.println("验证失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte[] bytes = generateCRC16ARCForSend(filePath); // 生成附带CRC的完整文件
|
||||||
|
if (verifyCRC16ARCByBytes(bytes)) { // 验证
|
||||||
|
System.out.println("验证成功");
|
||||||
|
}else {
|
||||||
|
System.out.println("验证失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(calculateCRC16ARC(new byte[]{1}));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
74
src/main/java/cn/whaifree/test/ShapleyValueDemo.java
Normal file
74
src/main/java/cn/whaifree/test/ShapleyValueDemo.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package cn.whaifree.test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ShapleyValueDemo {
|
||||||
|
|
||||||
|
static class Node {
|
||||||
|
int id;
|
||||||
|
double distance;
|
||||||
|
double strength;
|
||||||
|
|
||||||
|
Node(int id, double distance, double strength) {
|
||||||
|
this.id = id;
|
||||||
|
this.distance = distance;
|
||||||
|
this.strength = strength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<Node> nodes = new ArrayList<>();
|
||||||
|
// 添加三个节点的信息,这里以节点的 ID、距离和强度为例
|
||||||
|
nodes.add(new Node(1, 0.5, 0.8));
|
||||||
|
nodes.add(new Node(2, 0.8, 0.6));
|
||||||
|
nodes.add(new Node(3, 0.7, 0.7));
|
||||||
|
|
||||||
|
List<Double> shapleyValues = calculateShapleyValues(nodes);
|
||||||
|
|
||||||
|
System.out.println("Shapley Values:");
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
System.out.println("Node " + nodes.get(i).id + ": " + shapleyValues.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Double> calculateShapleyValues(List<Node> nodes) {
|
||||||
|
List<Double> shapleyValues = new ArrayList<>();
|
||||||
|
double[] marginalContributions = new double[nodes.size()];
|
||||||
|
|
||||||
|
// 计算每个节点的 Shapley 值
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
for (int j = 0; j < nodes.size(); j++) {
|
||||||
|
if (i != j) {
|
||||||
|
double valueWithI = getValue(getPlayerSubset(nodes.get(i), nodes.get(j)));
|
||||||
|
double valueWithoutI = getValue(getPlayerSubset(nodes.get(j)));
|
||||||
|
marginalContributions[i] += (valueWithI - valueWithoutI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shapleyValues.add(marginalContributions[i] / nodes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return shapleyValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟每个节点的贡献价值
|
||||||
|
public static double getValue(List<Node> nodes) {
|
||||||
|
// 这里可以根据实际情况编写计算价值的逻辑,这里简单地假设节点的贡献价值为距离与强度的乘积之和
|
||||||
|
double value = 0.0;
|
||||||
|
for (Node node : nodes) {
|
||||||
|
value += node.distance * node.strength;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成不包含给定节点的组合
|
||||||
|
public static List<Node> getPlayerSubset(Node excludedNode, Node... nodes) {
|
||||||
|
List<Node> subset = new ArrayList<>();
|
||||||
|
for (Node node : nodes) {
|
||||||
|
if (node != excludedNode) {
|
||||||
|
subset.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return subset;
|
||||||
|
}
|
||||||
|
}
|
39
src/main/java/cn/whaifree/test/byteStream.java
Normal file
39
src/main/java/cn/whaifree/test/byteStream.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package cn.whaifree.test;
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.Hash.LeetCode1;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/1 22:08
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class byteStream {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, ClassNotFoundException {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ObjectOutputStream objectOutputStream1 = new ObjectOutputStream(out);
|
||||||
|
objectOutputStream1.writeObject(new LeetCode1());
|
||||||
|
|
||||||
|
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
//转为对象
|
||||||
|
ObjectInputStream objectInputStream1 = new ObjectInputStream(byteArrayInputStream);
|
||||||
|
LeetCode1 o1 = (LeetCode1)objectInputStream1.readObject();
|
||||||
|
o1.test();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc.txt"));
|
||||||
|
LeetCode1 obj = new LeetCode1();
|
||||||
|
obj.test();
|
||||||
|
objectOutputStream.writeObject(obj);
|
||||||
|
|
||||||
|
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc.txt"));
|
||||||
|
LeetCode1 o = (LeetCode1) objectInputStream.readObject();
|
||||||
|
o.test();
|
||||||
|
objectOutputStream.close();
|
||||||
|
}
|
||||||
|
}
|
76
src/main/java/cn/whaifree/test/cglib.java
Normal file
76
src/main/java/cn/whaifree/test/cglib.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package cn.whaifree.test;
|
||||||
|
|
||||||
|
import net.sf.cglib.proxy.Enhancer;
|
||||||
|
import net.sf.cglib.proxy.MethodInterceptor;
|
||||||
|
import net.sf.cglib.proxy.MethodProxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/1 22:15
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class cglib {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 创建目标类的代理
|
||||||
|
TargetClassProxy proxy = new TargetClassProxy();
|
||||||
|
|
||||||
|
// 使用CGLIB创建代理对象
|
||||||
|
Enhancer enhancer = new Enhancer();
|
||||||
|
enhancer.setSuperclass(TargetClass.class);
|
||||||
|
enhancer.setCallback(proxy);
|
||||||
|
|
||||||
|
TargetClass targetProxy = (TargetClass) enhancer.create(); // Enhancer创建子类代理
|
||||||
|
|
||||||
|
// 调用代理对象的方法
|
||||||
|
targetProxy.doSomething();
|
||||||
|
System.out.println("===================");
|
||||||
|
targetProxy.doA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TargetClass extends TargetA{
|
||||||
|
public void doSomething() {
|
||||||
|
System.out.println("TargetClass: doSomething()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TargetA{
|
||||||
|
/**
|
||||||
|
* 加了final后,Enhancer不会增强
|
||||||
|
* <h4>
|
||||||
|
* Before method: doSomething <br>
|
||||||
|
* TargetClass: doSomething()<br>
|
||||||
|
* After method: doSomething<br>
|
||||||
|
* ===================<br>
|
||||||
|
* TargetA: doA()<br>
|
||||||
|
* </h4>
|
||||||
|
*
|
||||||
|
* 不加final
|
||||||
|
* <h4>
|
||||||
|
* Before method: doSomething<br>
|
||||||
|
* TargetClass: doSomething()<br>
|
||||||
|
* After method: doSomething<br>
|
||||||
|
* ===================<br>
|
||||||
|
* Before method: doA<br>
|
||||||
|
* TargetA: doA()<br>
|
||||||
|
* After method: doA<br>
|
||||||
|
* </h4>
|
||||||
|
*/
|
||||||
|
public void doA(){
|
||||||
|
|
||||||
|
System.out.println("TargetA: doA()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TargetClassProxy implements MethodInterceptor {
|
||||||
|
@Override
|
||||||
|
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||||
|
System.out.println("Before method: " + method.getName());
|
||||||
|
Object result = proxy.invokeSuper(obj, args); // 调用目标类的原始方法
|
||||||
|
System.out.println("After method: " + method.getName());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
43
src/main/java/cn/whaifree/test/hashDB.java
Normal file
43
src/main/java/cn/whaifree/test/hashDB.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package cn.whaifree.test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author whai文海
|
||||||
|
* @Date 2024/4/1 20:01
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class hashDB {
|
||||||
|
|
||||||
|
static final int[] hashes = {1,4}; // 哈希函数数组
|
||||||
|
|
||||||
|
// 3个库
|
||||||
|
private static final int NUM_SHARDS = 3;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 要分库的数据
|
||||||
|
String[] id = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
|
||||||
|
|
||||||
|
// 对每个数据计算哈希值并分配到库
|
||||||
|
for (String datum : id) {
|
||||||
|
int[] shard = getShard(datum);
|
||||||
|
System.out.println("Data: " + datum + " -> Shard: " + shard[0] + ", " + shard[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算数据的哈希值并分配到库
|
||||||
|
private static int[] getShard(String data) {
|
||||||
|
// 使用Java的hashCode()方法计算哈希值
|
||||||
|
int hash = data.hashCode();
|
||||||
|
// 取模运算得到库编号
|
||||||
|
int[] loc = new int[hashes.length];
|
||||||
|
for (int i = 0; i < loc.length; i++) {
|
||||||
|
loc[i] = Math.abs((hash ^ hashes[i]) % NUM_SHARDS) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,10 @@ package cn.whaifree.test;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.KeyGenerator;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @Author whai文海
|
* @Author whai文海
|
||||||
@ -28,3 +32,35 @@ public class testTry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SymmetricEncryptionUtil {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final String ALGORITHM = "AES";
|
||||||
|
private static byte[] SECRET_KEY = null; // 替换为你自己的密钥,密钥长度必须符合算法要求
|
||||||
|
|
||||||
|
public static byte[] encrypt(byte[] data) throws Exception {
|
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||||
|
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY, ALGORITHM);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||||
|
return cipher.doFinal(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decrypt(byte[] encryptedData) throws Exception {
|
||||||
|
Cipher cipher = Cipher.getInstance(ALGORITHM);
|
||||||
|
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY, ALGORITHM);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||||
|
return cipher.doFinal(encryptedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
SECRET_KEY = KeyGenerator.getInstance(ALGORITHM).generateKey().getEncoded();
|
||||||
|
System.out.println(new String(SECRET_KEY));
|
||||||
|
byte[] encrypt = SymmetricEncryptionUtil.encrypt("123456".getBytes());
|
||||||
|
System.out.println(new String(encrypt));
|
||||||
|
byte[] decrypt = SymmetricEncryptionUtil.decrypt(encrypt);
|
||||||
|
System.out.println(new String(decrypt));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user