添加泛型方法和并发编程相关代码

- 在`User`类中添加了泛型方法`test`
- 新增`FanXin`类包含并发安全的`openLogicFilter`方法
- 添加了`LeetCode47`到`LeetCode501`等新类和测试方法
- 在`p1`类中添加了处理数组和字符串的静态方法
- 更新了`TestController`类,添加了事务注解
- 新增了`beibao01`到`LeetCode84_1`等类和方法
- 添加了`RedisDataTest`类用于测试Redis的Hyperloglog和Bitmap数据结构

Default Changelist
fx.java
LeetCode47.java
LeetCode468.java
LeetCode491.java
LeetCode501.java
p1.java
TestController.java
Unversioned Files
D:\project\LeetCode\springDemo\.gitignore
D:\project\LeetCode\ForJdk17\src\main\java\cn\whaifree\redo\redo_all_240924\beibao01.java
D:\project\LeetCode\ForJdk17\src\main\java\cn\whaifree\redo\redo_all_240924\LeetCode11_2.java
D:\project\LeetCode\ForJdk17\src\main\java\cn\whaifree\redo\redo_all_240924\LeetCode51.java
D:\project\LeetCode\ForJdk17\src\main\java\cn\whaifree\redo\redo_all_240924\LeetCode84_1.java
D:\project\LeetCode\springDemo\mvnw
D:\project\LeetCode\springDemo\mvnw.cmd
D:\project\LeetCode\springDemo\src\test\java\cn\whaifree\springdemo\RedisData\RedisDataTest.java
This commit is contained in:
whaifree 2024-10-14 23:03:57 +08:00
parent 5f2cb9f209
commit 2036bf9ba2
12 changed files with 779 additions and 0 deletions

View File

@ -0,0 +1,177 @@
package cn.whaifree.interview.PDD;
import java.util.*;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/13 14:59
* @注释
*/
public class p1 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext hasNextLine 的区别
int i = in.nextInt();
int[] nums = new int[i];
for (int j = 0; j < i; j++) {
nums[j] = in.nextInt();
}
System.out.println(method(nums));
}
public static int method(int[] nums) {
int res = 0;
int pro = nums[0];
while (pro % 10 == 0) {
res++;
pro /= 10;
}
for (int i = 1; i < nums.length; i++) {
pro *= nums[i];
while (pro % 10 == 0) {
res++;
pro /= 10;
}
}
return res;
}
}
class p2{
public static void main(String[] args) {
/**
* abcd
* abzc
* b
* zyxwvutsrqponmlkjihgfedcba
* abcdefghijklmnopqrstuvx
*
* 5
* abc
* abz
* azyxwvutsrqponmlkjihgfedcb
* zyxwvutsrqponmlkjihgfedcba
* abcdefghijklmnopqrstuvwzyx
*
*/
// next("zyxwvutsrqponmlkjihgfedcba");
next("abc");
next("abcdefghijklmnopqrstuvwzyx");
// Scanner in = new Scanner(System.in);
// // 注意 hasNext hasNextLine 的区别
// while (in.hasNextInt()) { // 注意 while 处理多个 case
// int i = in.nextInt();
// for (int i1 = 0; i1 < i; i1++) {
// String next = in.next();
// System.out.println();
// }
// }
}
public static void next(String s) {
char[] charArray = s.toCharArray();
int i = charArray.length - 2;
while (i >= 0 && charArray[i] >= charArray[i + 1]) {
i--;
}
if (i >= 0) {
int j = charArray.length - 1;
while (j >= 0 && charArray[i] > charArray[j]) {
j--;
}
swap(charArray, i, j);
}
// reverse(charArray, i + 1, charArray.length - 1);
System.out.println(new String(Arrays.copyOf(charArray, i + 1)));
}
public static void reverse(char[] chars, int x, int y) {
while (x < y) {
swap(chars, x++, y--);
}
}
public static void swap(char[] chars, int x, int y) {
char tmp = chars[x];
chars[x] = chars[y];
chars[y] = tmp;
}
}
class p3{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext hasNextLine 的区别
while (in.hasNextInt()) {
int i = in.nextInt();
for (int i1 = 0; i1 < i; i1++) {
int count = in.nextInt();
int split = in.nextInt();
long[] ints = new long[count];
for (int j = 0; j < count; j++) {
ints[j] = in.nextLong();
}
System.out.println(in(ints, split) ? "True" : "False");
}
}
}
/**
* 长度为n的数组划分为k个子串
* 调整子串的顺序组成一个新的数组
* 判断数组和划分数k能否得到一个递增的序列
* @param nums
* @param split
*/
public static boolean in(long[] nums, int split) {
List<int[]> spl = new LinkedList<>();
int left = 0;
int right = 1;
while (right < nums.length) {
if (nums[right - 1] > nums[right]) {
spl.add(new int[]{left, right - 1});
left = right;
}
right++;
}
spl.add(new int[]{left, right - 1});
if (spl.size() > split) {
return false;
}
Collections.sort(spl, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return (int) (nums[o1[0]] - nums[o2[0]]) > 0 ? 1 : -1;
}
});
// Comparison method violates its general contract
for (int i = 1; i < spl.size(); i++) {
int[] before = spl.get(i - 1);
int[] me = spl.get(i);
if (nums[before[1]] > nums[me[0]]) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,39 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/14 15:48
* @注释
*/
public class LeetCode11_2 {
@Test
public void test() {
int[] height = {1, 8, 6, 2, 5, 4, 8, 3, 7};
Solution solution = new Solution();
int result = solution.maxArea(height);
System.out.println(result);
}
class Solution {
public int maxArea(int[] height) {
int left = 0;
int right = height.length - 1;
int maxSize = 0;
while (left < right) {
maxSize = Math.max(maxSize, (right - left) * Math.min(height[left], height[right]));
if (height[left] < height[right]) {
left++;
}else {
right--;
}
}
return maxSize;
}
}
}

View File

@ -0,0 +1,67 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/13 11:39
* @注释
*/
public class LeetCode468 {
@Test
public void test() {
System.out.println(Integer.parseInt("b", 16));
System.out.println(new Solution().validIPAddress("2001:0db8:85a3:0000:0:8A2E:0370:733a"));
}
class Solution {
public String validIPAddress(String queryIP) {
int i = queryIP.indexOf(".");
if (i == -1) {
return isV6(queryIP)? "IPv6" : "Neither";
}else {
return isV4(queryIP)? "IPv4" : "Neither";
}
}
public boolean isV4(String queryIp){
try {
String[] split = queryIp.split("\\.", -1);
if (split.length != 4) {
return false;
}
for (String s : split) {
if (s.length() > 1 && s.startsWith("0")) {
return false;
}
int i = Integer.parseInt(s);
if (i < 0 || i > 255) {
return false;
}
}
} catch (Exception e) {
return false;
}
return true;
}
public boolean isV6(String queryIp){
try {
String[] split = queryIp.split(":", -1);
if (split.length != 8) {
return false;
}
for (String s : split) {
int i = Integer.parseInt(s, 16);
if (s.length() > 4) {
return false;
}
}
} catch (Exception e) {
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,56 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/13 14:32
* @注释
*/
public class LeetCode47 {
@Test
public void test() {
int[] nums = {1,1,2};
List<List<Integer>> res = new Solution().permuteUnique(nums);
for (List<Integer> re : res) {
System.out.println(re);
}
}
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
boolean[] used = null;
public List<List<Integer>> permuteUnique(int[] nums) {
used = new boolean[nums.length];
back(nums);
return res;
}
public void back(int[] nums) {
if (temp.size() == nums.length) {
res.add(new ArrayList<>(temp));
return;
}
HashSet<Integer> set = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
if (used[i]||set.contains(nums[i])) {
continue;
}
set.add(nums[i]);
used[i] = true;
temp.add(nums[i]);
back(nums);
temp.remove(temp.size() - 1);
used[i] = false;
}
}
}
}

View File

@ -0,0 +1,63 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/13 14:10
* @注释
*/
public class LeetCode491 {
@Test
public void test() {
int[] nums = {4, 6, 7, 7};
System.out.println(new Solution().findSubsequences(nums));
}
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
backTracking(nums, 0);
return res;
}
/**
* 递增
*
* @param nums
* @param start
*/
public void backTracking(int[] nums, int start) {
if (path.size() >= 2) {
res.add(new ArrayList<>(path));
}
if (start > nums.length) {
return;
}
HashSet<Integer> set = new HashSet<>();
for (int i = start; i < nums.length; i++) {
if (!path.isEmpty() && nums[i] < path.get(path.size() - 1)) {
continue;
}
if (set.contains(nums[i])) {
continue;
}
set.add(nums[i]);
path.add(nums[i]);
backTracking(nums, i + 1);
path.remove(path.size()-1);
}
}
}
}

View File

@ -0,0 +1,69 @@
package cn.whaifree.redo.redo_all_240924;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/13 12:22
* @注释
*/
public class LeetCode501 {
@Test
public void test() {
TreeNode treeNode = TreeNode.constructTreeByArray(1, 0, 2, 2, 2);
int[] res = new Solution().findMode(treeNode);
System.out.println(Arrays.toString(res));
}
class Solution {
int now = 0;
int nowValue = 0;
int max = 0;
List<Integer> list = null;
public int[] findMode(TreeNode root) {
list = new ArrayList<>();
in(root);
int[] res = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
res[i] = list.get(i);
}
return res;
}
public void in(TreeNode root) {
if (root == null) {
return;
}
in(root.left);
if (nowValue == root.val) {
now++;
}else {
nowValue = root.val;
now = 1;
}
if (now > max) {
max = now;
list.clear();
list.add(root.val);
} else if (now == max) {
list.add(root.val);
}
in(root.right);
}
}
}

View File

@ -0,0 +1,94 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/14 14:44
* @注释
*/
public class LeetCode51 {
@Test
public void test() {
System.out.println(new Solution().solveNQueens(4));
}
class Solution {
boolean[][] map = null;
List<List<String>> res = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
map = new boolean[n][n];
back(0);
return res;
}
public void back(int row) {
if (row == map.length) {
List<String> path = new ArrayList<>();
for (int i = 0; i < map.length; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < map.length; j++) {
if (map[i][j]) {
sb.append("Q");
} else {
sb.append(".");
}
}
path.add(sb.toString());
}
res.add(new LinkedList<>(path));
return;
}
for (int i = 0; i < map.length; i++) {
if (isValid(row, i)) {
map[row][i] = true;
back(row + 1);
map[row][i] = false;
}
}
}
public boolean isValid(int x, int y) {
int n = map.length;
// 上边
for (int i = x; i >= 0; i--) {
if (map[i][y]) {
return false;
}
}
//
for (int j = y; j >= 0; j--) {
if (map[x][j]) {
return false;
}
}
// 左上45
for (int i = 1; i < n; i++) {
if (x - i >= 0 && y - i >= 0 && map[x - i][y - i]) {
return false;
}
}
// 右上
for (int i = 1; i < n; i++) {
if (x - i >= 0 && y + i < n && map[x - i][y + i]) {
return false;
}
}
return true;
}
}
}

View File

@ -0,0 +1,56 @@
package cn.whaifree.redo.redo_all_240924;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/14 15:57
* @注释
*/
public class LeetCode84_1 {
@Test
public void test() {
int[] heights = {2,1,2};
Solution solution = new Solution();
int max = solution.largestRectangleArea(heights);
System.out.println(max);
}
class Solution {
/**
* 前后遍历找到每个位置左右第一个小于他的
* @param heights
* @return
*/
public int largestRectangleArea(int[] heights) {
int[] tmp = heights;
int[] right = new int[tmp.length];
int[] left = new int[tmp.length];
left[0] = -1;
for (int i = 0; i < tmp.length ; i++) {
int index = i - 1;
while (index >= 0 && tmp[index] >= tmp[i]) {
index = left[index];
}
left[i] = index;
}
right[tmp.length - 1] = tmp.length;
for (int i = tmp.length - 2; i >= 0; i--) {
int index = i + 1;
while (index < tmp.length && tmp[index] >= tmp[i]) {
index = right[index];
}
right[i] = index;
}
int max = 0;
for (int i = 0; i < tmp.length; i++) {
max = Math.max(max, (right[i] - left[i] - 1) * tmp[i]);
}
return max;
}
}
}

View File

@ -0,0 +1,49 @@
package cn.whaifree.redo.redo_all_240924;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/14 15:26
* @注释
*/
public class beibao01 {
public static void main(String[] args) {
int[] values = {2, 3, 1, 5, 4, 3};
int[] weight = {2, 3, 1, 5, 2, 2};
int pkgSize = 6;
int result = bei(values, weight, pkgSize);
System.out.println(result);
}
/**
* 6 1
* 2 2 3 1 5 2 weight
* 2 3 1 5 4 3 value
*
* @param values
* @param weight
* @param pkgSize
* @return
*/
public static int bei(int[] values, int[] weight, int pkgSize) {
int[][] dp = new int[values.length][pkgSize + 1];
for (int i = weight[0]; i <= pkgSize; i++) {
dp[0][i] = values[0];
}
for (int i = 1; i < values.length; i++) {
for (int j = 0; j <= pkgSize; j++) {
if (j > weight[i]) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + values[i]);
}else {
dp[i][j] = dp[i - 1][j]; // 放不进去
}
}
}
return dp[values.length - 1][pkgSize];
}
}

View File

@ -1,5 +1,8 @@
package cn.whaifree.tech.java; package cn.whaifree.tech.java;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* @version 1.0 * @version 1.0
* @Author whai文海 * @Author whai文海
@ -14,6 +17,9 @@ public class fx {
class User <T extends Base, M,N,O, P> { // ,是并列的关系 class User <T extends Base, M,N,O, P> { // ,是并列的关系
public <T extends User> T test(User<? extends Base, ?, ?, ?, ?> user) {
return (T) user;
}
} }
@ -32,4 +38,23 @@ public class fx {
public void method() { public void method() {
new Book<BookBase>(); new Book<BookBase>();
} }
}
class FanXin{
class RaffleEntity {
}
interface ILogicFilter<T extends RaffleEntity> {
}
public Map<String, ILogicFilter<?>> logicFilterMap = new ConcurrentHashMap<>();
public <T extends RaffleEntity> Map<String, ILogicFilter<?>> openLogicFilter() {
return logicFilterMap;
}
} }

View File

@ -2,6 +2,7 @@ package cn.whaifree.springdemo.controller;
import cn.whaifree.springdemo.aspect.annotation.RateLimiter; import cn.whaifree.springdemo.aspect.annotation.RateLimiter;
import cn.whaifree.springdemo.constant.LimitType; import cn.whaifree.springdemo.constant.LimitType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -33,6 +34,7 @@ public class TestController {
*/ */
@PostMapping("addContainer") @PostMapping("addContainer")
@RateLimiter(key = "addContainer:", limitType = LimitType.USER, time = 5, count = 1) // 10s只能1次 @RateLimiter(key = "addContainer:", limitType = LimitType.USER, time = 5, count = 1) // 10s只能1次
@Transactional(rollbackFor = Exception.class)
public String addContainerInstanceToCluster(@RequestBody List<String> instances, int userId) { public String addContainerInstanceToCluster(@RequestBody List<String> instances, int userId) {
// 导入容器节点到集群中 // 导入容器节点到集群中
return addToCluster(instances, "clusterId", userId); return addToCluster(instances, "clusterId", userId);

View File

@ -0,0 +1,82 @@
package cn.whaifree.springdemo.RedisData;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.RedisTemplate;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/14 22:06
* @注释
*/
@SpringBootTest
@Slf4j
public class RedisDataTest {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testHyperloglog() {
String day1 = "visituser:article1:20211014";
redisTemplate.opsForHyperLogLog().add(day1, "user1");
redisTemplate.opsForHyperLogLog().add(day1, "user2");
redisTemplate.opsForHyperLogLog().add(day1, "user3");
redisTemplate.opsForHyperLogLog().add(day1, "user4");
redisTemplate.opsForHyperLogLog().add(day1, "user5");
// 获取值
long count = redisTemplate.opsForHyperLogLog().size(day1);
log.info("count day1:{}", count);//5 第一天有5个人访问这个文章
String day2 = "visituser:article1:20211015";
redisTemplate.opsForHyperLogLog().add(day2, "user1");
redisTemplate.opsForHyperLogLog().add(day2, "user2");
redisTemplate.opsForHyperLogLog().add(day2, "user3");
redisTemplate.opsForHyperLogLog().add(day2, "user4");
redisTemplate.opsForHyperLogLog().add(day2, "user6");
long count2 = redisTemplate.opsForHyperLogLog().size(day2);
log.info("count day2:{}", count2); //5
Long union = redisTemplate.opsForHyperLogLog().union(day1, day2);
log.info("union:{}", union);// 这个文章两天内的有6个人访问
}
@Test
public void testBitMap() {
// 定义一个字符串变量key用于存储Redis中存储位图的键
String key = "bitmap:article1";
// 在Redis位图中将key对应的值的第1个位设置为true这里用于记录文章1的阅读状态
redisTemplate.opsForValue().setBit(key, 1, true);
// 同样在Redis位图中将key对应的值的第2个位设置为true这里用于记录文章2的阅读状态
redisTemplate.opsForValue().setBit(key, 2, true);
// 检查Redis位图中key对应的值的第1个位是否为true打印结果
System.out.println(redisTemplate.opsForValue().getBit(key, 1));
// 创建BitFieldSubCommands对象用于执行更复杂的位图操作
BitFieldSubCommands subCommands = BitFieldSubCommands.create();
// 添加一个指令到subCommands中获取第11个位从0开始计数的64位整型值
subCommands.get(BitFieldSubCommands.BitFieldType.INT_64).valueAt(11);
// 添加一个指令到subCommands中将第11个位设置为64位整型值1
subCommands.set(BitFieldSubCommands.BitFieldType.INT_64).to(11);
// 执行subCommands中所有位图操作指令
redisTemplate.opsForValue().bitField(key, subCommands);
// 获取Redis位图中key对应的值的第11个位检查其是否为true
System.out.println(redisTemplate.opsForValue().getBit(key, 11));
}
}