leecode,rt_phm更新更新

This commit is contained in:
kevinding1125 2023-05-29 13:04:32 +08:00
parent 35ecb5b9c8
commit 1df4dce36e
5 changed files with 246 additions and 1 deletions

View File

@ -21,7 +21,7 @@ public class LC_1254_ClosedIsland {
{1, 0, 0, 0, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 0}
};
System.out.println(closedIsland(grid));
System.out.println(closedIsland2(grid));
}
@Test
@ -109,4 +109,32 @@ public class LC_1254_ClosedIsland {
//&&是短路与只要有一个不满足就不会判断后面的;&是逻辑与,会判断完后面的
return dfs1(grid, i, j + 1) & dfs1(grid, i, j - 1) & dfs1(grid, i + 1, j) & dfs1(grid, i - 1, j);
}
//思路:其实本质上就是在岛屿数量前面加上了封闭条件
//一个岛屿是否封闭:就是看他是否抵达边界,如果抵达边界则不封闭,反之则封闭
public int closedIsland2(int[][] grid) {
int result = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 0 && dfs(grid, i, j)) {
result++;
}
}
}
return result;
}
public boolean dfs(int[][] grid, int i, int j) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length) {
return false;//抵达边界了不行
}
if (grid[i][j] == 1) {
return true;//遇上水
}
grid[i][j] = 1;
//四个方向都要是同时不能只判断一个所以使用&而不是&&
return dfs(grid, i - 1, j) & dfs(grid, i + 1, j) & dfs(grid, i, j - 1) & dfs(grid, i, j + 1);
}
}

View File

@ -1,5 +1,7 @@
package com.markilue.leecode.hot100.interviewHot.graph;
import com.sun.crypto.provider.PBEWithMD5AndDESCipher;
import java.util.*;
/**
@ -181,4 +183,64 @@ public class LC_127_LadderLength {
}
return distance < 2;
}
public int ladderLength3(String beginWord, String endWord, List<String> wordList) {
//TODO 1.放入HashSet方便判断
HashSet<String> wordSet = new HashSet<>(wordList);
if (wordSet.size() == 0 || !wordSet.contains(endWord)) {
return 0;//到不了
}
wordSet.remove(beginWord);
//TODO 2.创建一个queue存放对应的word
HashSet<String> visited = new HashSet<>();
ArrayDeque<String> queue = new ArrayDeque<>();
queue.push(beginWord);
int step = 1;//最begin开始至少走一步
while (!queue.isEmpty()) {
int curSize = queue.size();
for (int i = 0; i < curSize; i++) {
String curWord = queue.pollFirst();
//任意改变一个字母判断在不在HashSet里面或者是不是endWord
if (changeEveryChar(curWord, endWord, wordSet, visited, queue)) {
return step + 1;
}
}
step++;
}
return 0;
}
private boolean changeEveryChar(String curWord, String endWord, Set<String> wordSet, Set<String> visited, Deque<String> queue) {
char[] charArray = curWord.toCharArray();
for (int i = 0; i < charArray.length; i++) {
char originalLetter = charArray[i];
//变换成26个字母,判断在不在wordSet里
for (char j = 'a'; j <= 'z'; j++) {
if (j == originalLetter) continue;
charArray[i] = j;
String changeWord = String.valueOf(charArray);
//wordSet里面包不包含
if (wordSet.contains(changeWord)) {
if (endWord.equals(changeWord)) {
return true;//抵达终点
}
if (!visited.contains(changeWord)) {
queue.addLast(changeWord);
visited.add(changeWord);
}
}
}
charArray[i] = originalLetter;
}
return false;
}
}

View File

@ -0,0 +1,51 @@
package com.markilue.leecode.hot100.interviewHot.singlestack;
import java.util.ArrayDeque;
import java.util.Deque;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.interviewHot.singlestack
*@Author: markilue
*@CreateTime: 2023-05-29 09:46
*@Description: TODO 力扣84 柱状图中最大的矩形
*@Version: 1.0
*/
public class LC_84_LargestRectangleArea {
//为什么需要单调栈:其实本质上当前位置的面最大值依赖于左右两边的宽度最大可以延展到哪里
//而当前位置需要延展到两边,所以这里使用单调栈来记录
public int largestRectangleArea(int[] heights) {
Deque<Integer> stack = new ArrayDeque<>();
int n = heights.length;
int[] left = new int[n];
int[] right = new int[n];
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {//寻找第一个比当前值小的值
stack.pop();
}
left[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
stack.clear();
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
stack.pop();
}
right[i] = stack.isEmpty() ? n : stack.peek();
stack.push(i);
}
//计算每一个位置的面积,求最大值
int result = 0;
for (int i = 0; i < n; i++) {
result = Math.max(result, heights[i] * (right[i] - left[i] - 1));
}
return result;
}
}

View File

@ -0,0 +1,82 @@
package com.markilue.leecode.hot100.interviewHot.union_find;
import org.junit.Test;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.interviewHot.union_find
*@Author: markilue
*@CreateTime: 2023-05-29 11:00
*@Description: TODO 力扣684 冗余连接:
*@Version: 1.0
*/
public class LC_684_FindRedundantConnection {
@Test
public void test() {
int[][] edges = {
{1, 4},
{3, 4},
{1, 3},
{1, 2},
{4, 5},
};
System.out.println(Arrays.toString(findRedundantConnection(edges)));
}
int n;//节点的数量
int[] father;//父节点矩阵记录每个子节点的父节点
//初始化父节点矩阵
private void init(int[] father) {
for (int i = 0; i < father.length; i++) {
father[i] = i;
}
}
//寻找一个节点的父节点是谁
private int find(int u) {
if (u == father[u]) {
return u;
}
father[u] = find(father[u]);
return father[u];
}
//将两个节点 并起来
private void join(int u, int v) {
u = find(u);//这里是核心
v = find(v);//这里是核心
if (u == v) return;//已经在一个集合里面了
//不是找v的father是u而是v的father是u的father
father[v] = u;//合并在一起
}
//判断两个节点在不在一个并查集里面
private boolean same(int u, int v) {
int fatherU = find(u);
int fatherV = find(v);
return fatherU == fatherV;//已经在一个集合里面了
}
//本质上就是判断是不是有环如果有环应该拆哪一个:使用并查集实现
public int[] findRedundantConnection(int[][] edges) {
n = 1005;
father = new int[n];
init(father);
for (int[] edge : edges) {
if (same(edge[0], edge[1])) {
//在一个并查集里面
return edge;
} else {
//不在一个并查集里面,那么就把他们两加入并连起来
join(edge[0], edge[1]);
}
}
return null;
}
}

View File

@ -0,0 +1,22 @@
package com.markilue.leecode.hot100.interviewHot.union_find;
import org.junit.Test;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.interviewHot.union_find
*@Author: markilue
*@CreateTime: 2023-05-29 11:00
*@Description: TODO 力扣685 冗余连接II:
*@Version: 1.0
*/
public class LC_685_FindRedundantConnection {
public int[] findRedundantDirectedConnection(int[][] edges) {
return null;
}
}