feat(leetcode): 添加多个 LeetCode 问题的解决方案

- 新增 LeetCode 79、120、994、1137 的解决方案
- 优化 ExceptionDemo 类,添加 main 方法的无限循环
- 更新 SPIService接口,增加 ServiceLoader 加载服务的示例代码
This commit is contained in:
whai 2024-11-20 11:47:50 +08:00
parent 14973b69dd
commit 1463d05d37
6 changed files with 363 additions and 0 deletions

View File

@ -0,0 +1,36 @@
package cn.whaifree.leetCode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/11/19 22:39
* @注释
*/
public class LeetCode1137 {
@Test
public void test() {
Solution solution = new Solution();
System.out.println(solution.tribonacci(1));
}
class Solution {
public int tribonacci(int n) {
if (n == 0) {
return 0;
}
if (n == 1 || n == 2) {
return 1;
}
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
return dp[n];
}
}
}

View File

@ -0,0 +1,76 @@
package cn.whaifree.leetCode;
import org.junit.Test;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/11/19 22:43
* @注释
*/
public class LeetCode120 {
@Test
public void test() {
Solution1 solution = new Solution1();
System.out.println(solution.minimumTotal(List.of(List.of(2), List.of(3, 4), List.of(6, 5, 7), List.of(4, 1, 8, 3))));
}
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
return in(triangle, 0, 0);
}
public int in(List<List<Integer>> triangle, int level, int col) {
if (level == triangle.size()) {
return 0;
}
int now = triangle.get(level).get(col);
int left = in(triangle, level + 1, col);
int right = in(triangle, level + 1, col + 1);
if (left < right) {
return left + now;
} else {
return right + now;
}
}
}
class Solution1 {
/**
* dp[i][j] 表示从0 0到i j的最小路径和
*
* dp[i][j] = min(dp[i-1][j-1] dp[i-1][j]) + value[i][j]
*
* 2
3 4
6 5 7 最左边的只能由右上角推出 最右边只能由左上角推出 6<--3 7<--4
4 1 8 3
* @param triangle
* @return
*/
public int minimumTotal(List<List<Integer>> triangle) {
int n = triangle.size();
int[][] dp = new int[n][n];
dp[0][0] = triangle.get(0).get(0);
for (int i = 1; i < n; i++) {
// 从第一层开始
dp[i][0] = dp[i - 1][0] + triangle.get(i).get(0); // 每一层第一个元素只有一个来源
// 遍历第一层除了第一个以外所有节点
for (int j = 1; j < i; j++) {
dp[i][j] = Math.min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle.get(i).get(j);
}
// 还要考虑一行最后一个节点,只有一个来源
dp[i][i] = dp[i - 1][i - 1] + triangle.get(i).get(i);
}
// 获取到n-1层的所有价值取最小值
int min = dp[n - 1][0];
for (int i = 1; i < n; i++) {
min = Math.min(min, dp[n - 1][i]);
}
return min;
}
}
}

View File

@ -0,0 +1,159 @@
package cn.whaifree.leetCode;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/11/19 16:56
* @注释
*/
public class LeetCode79 {
@Test
public void test() {
// char[][] board = new char[][]{
// {'A', 'B', 'C', 'E'},
// {'S', 'F', 'C', 'S'},
// {'A', 'D', 'E', 'E'}
// };
// String word = "ABCCED";
// System.out.println(new Solution().exist(board, word));
/**
* 输入board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出false
*/
char[][] board2 = new char[][]{
// [["a","a","a","a"],["a","a","a","a"],["a","a","a","a"]]
{'A', 'A', 'A', 'A'},
{'A', 'A', 'A', 'A'},
{'A', 'A', 'A', 'A'}
};
String word2 = "B";
System.out.println(new Solution().exist(board2, word2));
}
class Solution1 {
List<int[]> path = new ArrayList<>();
int nowIndex = 0;
public int[][] direct = new int[][]{
{0, 1},
{0, -1},
{1, 0},
{-1, 0}
};
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
nowIndex++;
path.add(new int[]{i, j});
if (back(board, i, j, word, new int[]{i, j})) {
return true;
}
path.remove(path.size() - 1);
nowIndex--;
}
}
return false;
}
public boolean back(char[][] board, int x, int y, String word, int[] before) {
if (nowIndex == word.length()) {
for (int i = 0; i < path.size(); i++) {
System.out.println(Arrays.toString(path.get(i)));
}
return true;
}
char nextExpect = word.charAt(nowIndex);
for (int i = 0; i < direct.length; i++) {
int nextX = x + direct[i][0];
int nextY = y + direct[i][1];
if (nextX < 0 || nextX >= board.length || nextY < 0 || nextY >= board[0].length) {
continue;
}
if (nextX == before[0] && nextY == before[1]) {
continue;
}
if (board[nextX][nextY] == nextExpect) {
nowIndex++;
path.add(new int[]{nextX, nextY});
if (back(board, nextX, nextY, word, new int[]{x, y})) {
return true;
}
path.remove(path.size() - 1);
nowIndex--;
}
}
return false;
}
}
class Solution {
int nowIndex = 0;
public int[][] direct = new int[][]{
{0, 1},
{0, -1},
{1, 0},
{-1, 0}
};
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] != word.charAt(0)) {
continue;
}
nowIndex++;
char tmp = board[i][j];
board[i][j] = '0';
if (back(board, i, j, word)) {
return true;
}
board[i][j] = tmp;
nowIndex--;
}
}
return false;
}
public boolean back(char[][] board, int x, int y, String word) {
if (nowIndex == word.length()) {
return true;
}
char nextExpect = word.charAt(nowIndex);
for (int i = 0; i < direct.length; i++) {
int nextX = x + direct[i][0];
int nextY = y + direct[i][1];
if (nextX < 0 || nextX >= board.length || nextY < 0 || nextY >= board[0].length) {
continue;
}
if (board[nextX][nextY] == '0') {
continue;
}
if (board[nextX][nextY] == nextExpect) {
char tmp = board[nextX][nextY];
board[nextX][nextY] = '0';
nowIndex++;
if (back(board, nextX, nextY, word)) {
return true;
}
board[nextX][nextY] = tmp;
nowIndex--;
}
}
return false;
}
}
}

View File

@ -0,0 +1,80 @@
package cn.whaifree.leetCode;
import org.junit.Test;
import java.security.PublicKey;
import java.util.*;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/11/18 21:48
* @注释
*/
public class LeetCode994 {
@Test
public void test() {
Solution solution = new Solution();
int[][] grid = {{2, 1, 1}, {1, 1, 0}, {0, 1, 1}};
System.out.println(solution.orangesRotting(grid));
}
class Solution {
public int[][] direct = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
/**
* 深度优先遍历
* - 如果是腐烂的全部进入队列
* - 每次获取队列大小队列内为本time内的腐烂
* - 把队列内的周围的全部放入
*
* 统计新鲜橘子的数量如果数量最后还是?>0则表示无法全部腐烂
*
* @param grid
* @return
*/
public int orangesRotting(int[][] grid) {
int fresh = 0;
Queue<int[]> queue = new ArrayDeque<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 2) {
queue.offer(new int[]{i, j});
}else if (grid[i][j] == 1) {
fresh++;
}
}
}
int res = 0;
while (!queue.isEmpty() && fresh > 0) {
res++; // 表示一层
// 拿出所有腐烂的橘子
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] poll = queue.poll();
for (int dir = 0; dir < direct.length; dir++) {
int x = poll[0] + direct[dir][0];
int y = poll[1] + direct[dir][1];
if (x >= 0 && x < grid.length && y >= 0 && y < grid[0].length ) {
if (grid[x][y] == 1) {
// 如果是新鲜的
grid[x][y] = 2;
fresh--;
queue.offer(new int[]{x, y});
}
}
}
}
}
return fresh == 0 ? res : -1;
}
}
}

View File

@ -18,6 +18,9 @@ public interface SPIService {
ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class);
for (SPIService spiService : load) {
System.out.println(spiService);
}
Iterator<SPIService> iterator = load.iterator();
while (iterator.hasNext()) {
SPIService next = iterator.next();

View File

@ -10,6 +10,12 @@ import org.junit.Test;
*/
public class ExceptionDemo {
public static void main(String[] args) {
while (true) {
}
}
@Test
public void testException() {
try {
@ -25,6 +31,7 @@ public class ExceptionDemo {
class CustomRuntimeException extends RuntimeException {
}
public void testRuntimeException() {
throw new CustomRuntimeException();
}
@ -34,9 +41,11 @@ public class ExceptionDemo {
public void testCustomException() throws CustomCheckException {
method();
}
public void method() throws CustomCheckException {
throw new CustomCheckException("自定义异常");
}
class CustomCheckException extends Exception {
public CustomCheckException(String message) {
super(message);