新增Kama99和LeetCode797两个图形算法题解

- 添加Kama99类,实现了一个算法来计算二维数组中岛屿的数量
- 添加LeetCode797类,实现了寻找所有从源到目标的路径的算法
- 新增p1类,用于解决特定的字符串问题
- 在TestCacheThreadPool中添加了非公平锁的示例代码
- 在ThreadDemo1中添加了广度优先搜索的实现
This commit is contained in:
whaifree 2024-10-17 23:22:31 +08:00
parent 3557e7b1c2
commit e6d23febec
5 changed files with 199 additions and 0 deletions

View File

@ -0,0 +1,24 @@
package cn.whaifree.interview.hzyh;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/17 18:23
* @注释
*/
public class p1 {
/**
* abcdefgihjklmnopqrstuvwxyz
*
* 中包含问号?
*
* 判断最少需要多少长可以涵盖这26个字符?是万能的
*
* @param args
*/
public static void main(String[] args) {
}
}

View File

@ -0,0 +1,65 @@
package cn.whaifree.leetCode.Graph;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/17 16:26
* @注释
*/
public class Kama99 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int[][] input = new int[a][b];
boolean[][] visited = new boolean[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
input[i][j] = scanner.nextInt();
}
}
int res = 0;
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
if (!visited[i][j] && input[i][j] == 1) {
// 没有走过的节点+为陆地1
res++;
method(input, visited, i, j);
}
}
}
System.out.println(res);
}
public static int method(int[][] input, boolean[][] looking, int x, int y) {
int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 表示四个方向
int res = 0;
int[] item = new int[]{x, y};
looking[x][y] = true;
Deque<int[]> queue = new LinkedList<>();
queue.add(item);
while (!queue.isEmpty()) {
int[] pop = queue.pop();
int x1 = pop[0];
int y1 = pop[1];
for (int i = 0; i < 4; i++) {
int nextX = x1 + dir[i][0];
int nextY = y1 + dir[i][1];
if (nextX >= 0 && nextX < input.length && nextY >= 0 && nextY < input[0].length) {
if (!looking[nextX][nextY] && input[nextX][nextY] == 1) { // 只有1才遍历这样就可以保证只在小岛屿内
// 下一次的节点没有遍历过并且为1
queue.add(new int[]{nextX, nextY});
looking[nextX][nextY] = true; // 进入队列就标志看过了
}
}
}
}
return res;
}
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.leetCode.Graph;
import org.junit.Test;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/10/17 18:09
* @注释
*/
public class LeetCode797 {
@Test
public void test() {
int[][] graph = {{4,3,1},{3,2,4},{3},{4},{}};
List<List<Integer>> res = new Solution().allPathsSourceTarget(graph);
res.forEach(System.out::println);
}
class Solution {
List<List<Integer>> res = null;
List<Integer> path = null;
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
res = new java.util.ArrayList<>();
path = new java.util.ArrayList<>();
path.add(0);
dfs(graph, 0);
return res;
}
public void dfs(int[][] graph, int cur) {
if (!path.isEmpty() && graph.length - 1 == path.get(path.size() - 1)) {
res.add(new java.util.ArrayList<>(path));
return;
}
int[] ints = graph[cur];
for (int i = 0; i < ints.length; i++) {
path.add(ints[i]);
dfs(graph, ints[i]); // 0-4
path.remove(path.size() - 1);
}
}
}
}

View File

@ -271,4 +271,36 @@ public class TestCacheThreadPool {
} }
}
class NoFairLock {
public static void main(String[] args) {
// 公平锁和非公平锁的主要区别在于公平锁会检查是否有线程在等待有就直接封装成Node而非公平锁无论如何都会去试一下能不能获取锁
// 公平锁和非公平锁释放的过程是完全一样的都是通知CLH的后继节点
ReentrantLock lock = new ReentrantLock(false);
for (int i = 0; i < 15; i++) {
int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(finalI);
lock.lock();
System.out.println(Thread.currentThread().getName() + " acquired the lock");
// 模拟业务操作
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
System.out.println(Thread.currentThread().getName() + " released the lock");
lock.unlock();
}
}
}, "Thread-" + i).start();
}
}
} }

View File

@ -275,6 +275,37 @@ class mockException{
System.out.println(s); System.out.println(s);
} }
private int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 表示四个方向
/**
*
* @param grid 原地板
* @param visited 浏览的点
* @param x 起始位置
* @param y
*/
public void bfs(char[][] grid, boolean[][] visited, int x, int y) {
Queue<int[]> queue = new LinkedList<>(); // 定义队列
queue.offer(new int[]{x, y}); // 起始节点加入队列
visited[x][y] = true; // 只要加入队列立刻标记为访问过的节点
while (!queue.isEmpty()) { // 开始遍历队列里的元素
int[] cur = queue.poll(); // 从队列取元素
int curx = cur[0];
int cury = cur[1]; // 当前节点坐标
for (int i = 0; i < 4; i++) { // 开始想当前节点的四个方向左右上下去遍历
int nextx = curx + dir[i][0];
int nexty = cury + dir[i][1]; // 获取周边四个方向的坐标
if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue; // 坐标越界了直接跳过
if (!visited[nextx][nexty]) { // 如果节点没被访问过
queue.offer(new int[]{nextx, nexty}); // 队列添加该节点为下一轮要遍历的节点
visited[nextx][nexty] = true; // 只要加入队列立刻标记避免重复访问
}
}
}
}
} }