leecode更新

This commit is contained in:
markilue 2023-03-15 11:52:13 +08:00
parent 438001b2d4
commit 89885c0e53
4 changed files with 315 additions and 0 deletions

View File

@ -0,0 +1,93 @@
package com.markilue.leecode.hot100;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-03-15 10:04
*@Description:
* TODO 力扣169题 多数元素:
* 给定一个大小为 n 的数组 nums 返回其中的多数元素多数元素是指在数组中出现次数 大于 n/2 的元素
* 你可以假设数组是非空的并且给定的数组总是存在多数元素
*@Version: 1.0
*/
public class T60_MajorityElement {
@Test
public void test() {
int[] nums = {3, 2, 3};
System.out.println(majorityElement(nums));
}
/**
* 思路:按个遍历记录次数
* 由于数字大小不一定所以不太好用数组记录使用map记录
* 速度击败31.94% 内存击败22.92% 10ms
* @param nums
* @return
*/
public int majorityElement(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<>();//<num,count>
int length = nums.length;
for (int num : nums) {
int count = map.getOrDefault(num, 0) + 1;
if (count > length / 2) return num;
map.put(num, count);
}
return 0;
}
/**
* 官方最快
* 速度击败100% 内存击败61.22%
* @param nums
* @return
*/
public int majorityElement1(int[] nums) {
return dfs(nums, 0);
}
private int dfs(int[] nums, int start) {
int cnt = 1;
for (int i = start + 1; i < nums.length; i++) {
if (nums[i] == nums[start]) cnt++;
else cnt--;
if (cnt == 0) return dfs(nums, i + 1);
}
return nums[start];
}
/**
* 上述思路的正常版
* 莫斯投票法
* @param nums
* @return
*/
public int majorityElement2(int[] nums) {
int count = 1;
int maj = nums[0];
for (int i = 1; i < nums.length; i++) {
if (maj == nums[i])
count++;
else {
count--;//大于n/2的最后一定不会被减完
if (count == 0) {
maj = nums[i + 1];
}
}
}
return maj;
}
}

View File

@ -0,0 +1,58 @@
package com.markilue.leecode.hot100;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-03-15 10:26
*@Description:
* TODO 力扣198 打家劫舍:
* 你是一个专业的小偷计划偷窃沿街的房屋
* 每间房内都藏有一定的现金影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统
* 如果两间相邻的房屋在同一晚上被小偷闯入系统会自动报警
* 给定一个代表每个房屋存放金额的非负整数数组
* 计算你 不触动警报装置的情况下 一夜之内能够偷窃到的最高金额
*@Version: 1.0
*/
public class T61_Rob {
/**
* 思路:动态规划法可以分为当前位置偷或者当前位置不偷
* @param nums
* @return
*/
public int rob(int[] nums) {
int[][] dp = new int[nums.length][2];
dp[0][0] = 0;//不偷
dp[0][1] = nums[0];//
for (int i = 1; i < nums.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);
dp[i][1] = dp[i - 1][0] + nums[i];
}
return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]);
}
//滚动数组
public int rob1(int[] nums) {
int dp0 = 0;//不偷
int dp1 = nums[0];//
int temp;
for (int i = 1; i < nums.length; i++) {
temp = dp0;
dp0 = Math.max(dp0, dp1);
dp1 = temp + nums[i];
}
return Math.max(dp0, dp1);
}
}

View File

@ -0,0 +1,113 @@
package com.markilue.leecode.hot100;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-03-15 10:36
*@Description:
* TODO 力扣200 岛屿数量:
* 给你一个由 '1'陆地 '0'组成的的二维网格请你计算网格中岛屿的数量
* 岛屿总是被水包围并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成
* 此外你可以假设该网格的四条边均被水包围
*@Version: 1.0
*/
public class T62_NumIslands {
@Test
public void test() {
char[][] grid = {
{'1', '1', '1'},
{'0', '1', '0'},
{'1', '1', '1'},
};
System.out.println(numIslands(grid));
}
@Test
public void test1() {
char[][] grid = {
{'1', '0', '1', '1', '1'},
{'1', '0', '1', '0', '1'},
{'1', '1', '1', '0', '1'},
};
System.out.println(numIslands(grid));
}
boolean[][] used;
/**
* 思路:动态规划好像不动态规划也行
* 好像不行 前面的状态可能因为右面的而改变
* 贪心?碰上相连的就把与他相连的所有都变成 0
* @param grid
* @return
*/
public int numIslands(char[][] grid) {
used = new boolean[grid.length][grid[0].length];
int result = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
clear(grid, i, j);
result++;
}
}
}
return result;
}
//贪心清空
public void clear(char[][] grid, int i, int j) {
if (i == grid.length || j == grid[0].length || j < 0 || i < 0) {
return;
}
if (grid[i][j] == '1' && !used[i][j]) {
used[i][j] = true;
grid[i][j] = '0';
clear(grid, i + 1, j);
clear(grid, i - 1, j);//注意还要清理上边
clear(grid, i, j - 1);//注意还要清理左边
clear(grid, i, j + 1);
}
}
void dfs(char[][] grid, int r, int c) {
if(r < 0 || c < 0 || r >= grid.length || c >= grid[0].length || grid[r][c] == '0'){
return;
}
grid[r][c] = '0';
dfs(grid,r + 1,c);
dfs(grid,r - 1,c);
dfs(grid,r,c - 1);
dfs(grid,r,c + 1);
}
//官方最快方法:与本人一致但是他通过先把当前置为0,可以不用使用used数组
public int numIslands1(char[][] grid) {
if(grid == null || grid.length == 0){
return 0;
}
int count = 0;
for(int i = 0;i < grid.length;i++){
for(int j = 0;j < grid[0].length;j++){
if(grid[i][j] == '1'){
count++;
dfs(grid,i,j);
}
}
}
return count;
}
}

View File

@ -0,0 +1,51 @@
package com.markilue.leecode.hot100;
import com.markilue.leecode.listnode.ListNode;
import com.markilue.leecode.listnode.ListNodeUtils;
import org.junit.Test;
import java.util.List;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-03-15 11:29
*@Description:
* TODO 力扣206题 反转链表:
* 给你单链表的头节点 head 请你反转链表并返回反转后的链表
*@Version: 1.0
*/
public class T63_ReverseList {
@Test
public void test(){
ListNode root = ListNodeUtils.build(new int[]{1, 2, 3, 4, 5});
ListNodeUtils.print(reverseList(root));
}
/**
* 思路:使用另一个链表记录
* 速度击败100% 内存击败33.3%
* @param head
* @return
*/
public ListNode reverseList(ListNode head) {
ListNode fake = new ListNode();
ListNode temp = head;
ListNode tempNext;
while (temp != null) {
ListNode listNode = new ListNode(temp.val);
listNode.next = fake.next;
fake.next = listNode;
temp=temp.next;
}
return fake.next;
}
}