leecode更新

This commit is contained in:
markilue 2023-05-09 13:13:41 +08:00
parent 357262888d
commit 4080e880b3
7 changed files with 373 additions and 4 deletions

View File

@ -35,4 +35,24 @@ public class T47_114_Flatten {
}
}
//二刷:本质上就是找到左子树的最右节点把他的右子树拼到这个最右节点上
public void flatten1(TreeNode root) {
if (root == null) {
return;
}
if (root.left != null) {
TreeNode left = root.left;
while (left.right != null) {
left = left.right;
}
left.right = root.right;
root.right = root.left;
root.left = null;
}
flatten1(root.right);
}
}

View File

@ -0,0 +1,60 @@
package com.markilue.leecode.hot100.second;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-09 10:00
*@Description:
* TODO 力扣121 买卖股票的最佳时机:
* 给定一个数组 prices 它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格
* 你只能选择 某一天 买入这只股票并选择在 未来的某一个不同的日子 卖出该股票设计一个算法来计算你所能获取的最大利润
* 返回你可以从这笔交易中获取的最大利润如果你不能获取任何利润返回 0
*@Version: 1.0
*/
public class T48_121_MaxProfit {
//只能某一天买入:贪心
public int maxProfit(int[] prices) {
int min = prices[0];
int maxProfit = 0;
int cur;
for (int i = 1; i < prices.length; i++) {
cur = prices[i] - min;
if (cur > maxProfit) maxProfit = cur;
if (min > prices[i]) min = prices[i];
}
return maxProfit;
}
//只能某一天买入:动态规划
public int maxProfit1(int[] prices) {
int[][] dp = new int[prices.length][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], prices[i] + dp[i - 1][1]);
dp[i][1] = Math.max(-prices[i], dp[i - 1][1]);
}
return Math.max(dp[prices.length - 1][0], dp[prices.length - 1][1]);
}
//只能某一天买入:滚动数组优化
public int maxProfit2(int[] prices) {
int dp0 = 0;
int dp1 = -prices[0];
for (int i = 1; i < prices.length; i++) {
dp0 = Math.max(dp0, prices[i] + dp1);
dp1 = Math.max(-prices[i], dp1);
}
return Math.max(dp0, dp1);
}
}

View File

@ -0,0 +1,64 @@
package com.markilue.leecode.hot100.second;
import com.markilue.leecode.tree.TreeNode;
import com.markilue.leecode.tree.TreeUtils;
import org.junit.Test;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-09 10:16
*@Description: TODO 力扣124 二叉树中的最大路径和:
*@Version: 1.0
*/
public class T49_124_MaxPathSum {
@Test
public void test() {
TreeNode root = TreeUtils.structureTree(Arrays.asList(-10, 9, 20, null, null, 15, 7), 0);
System.out.println(maxPathSum(root));
}
int maxSum = Integer.MIN_VALUE;
/**
* 本质上就是:计算完左右子树的最大和来确定要左边还是要右边然后继续遍历;而当前位置的最大就是左右之和+自己或者左边或者右边
* @param root
* @return
*/
public int maxPathSum(TreeNode root) {
maxSum = root.val;
getMax(root);
return maxSum;
}
/**
* 获取当前节点位置的最大和
* @param root
* @return
*/
public int getMax(TreeNode root) {
if (root == null) {
return 0;
}
int left = Math.max(getMax(root.left), 0);
int right = Math.max(getMax(root.right), 0);
//为什么不考虑不要当前的:因为不要当前的在子树当中就已经考虑过了
int curMax = root.val + left + right;
if (maxSum < curMax) maxSum = curMax;
return root.val+Math.max(left,right);
}
}

View File

@ -1,5 +1,7 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
@ -18,6 +20,12 @@ import java.util.HashSet;
*/
public class T50_128_LongestConsecutive {
@Test
public void test() {
int[] nums = {100, 4, 200, 1, 3, 2};
System.out.println(longestConsecutive2(nums));
}
/**
* 思路:用hashset记录所有记录最大的值
@ -95,5 +103,32 @@ public class T50_128_LongestConsecutive {
return result;
}
//二刷:利用hashset来使用O(1)获取其邻接的值
public int longestConsecutive2(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
int maxLength = 0;
//挨个遍历:注意这里用set遍历,速度会快很多
for (int num : set) {
if (!set.contains(num - 1)) {
int curLength = 1;
while (set.contains(num + 1)) {
curLength++;
num++;
}
if (curLength > maxLength) maxLength = curLength;
}
}
return maxLength;
}
}

View File

@ -0,0 +1,33 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-09 10:54
*@Description: TODO 力扣136 只出现一次的数字
*@Version: 1.0
*/
public class T51_136_SingleNumber {
@Test
public void test(){
int[] nums={2,2,1};
// int[] nums={2};
System.out.println(singleNumber(nums));
}
//只出现一次其他都两次可以考虑使用位运算:异或异或两次相同的数就会变为原来的数
public int singleNumber(int[] nums) {
int cur = 0;//0异或任何数都等于那个数
for (int num : nums) {
cur ^= num;
}
return cur;
}
}

View File

@ -0,0 +1,107 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-09 11:03
*@Description: TODO 力扣139 单词拆分
*@Version: 1.0
*/
public class T52_139_WordBreak {
@Test
public void test() {
String s = "leetcode";
List<String> wordDict = Arrays.asList("leet", "code");
System.out.println(wordBreak(s, wordDict));
}
@Test
public void test1() {
String s = "applepenapple";
List<String> wordDict = Arrays.asList("apple", "pen");
System.out.println(wordBreak(s, wordDict));
}
//7ms
public boolean wordBreak(String s, List<String> wordDict) {
//以i开头,以j结尾的s能否凑出来
boolean[] dp = new boolean[s.length() + 1];
dp[0] = true;
HashSet<String> set = new HashSet<>(wordDict);
for (int i = 0; i < dp.length; i++) {
for (int j = i; j >= 0; j--) {
if (dp[j] && set.contains(s.substring(j, i))) {
dp[i] = true;
}
}
}
return dp[s.length()];
}
//3ms
public boolean wordBreak1(String s, List<String> wordDict) {
//以i开头,以j结尾的s能否凑出来
boolean[] dp = new boolean[s.length() + 1];
dp[0] = true;
for (int i = 0; i < dp.length; i++) {
for (String s1 : wordDict) {
int length = s1.length();
if (i >= length) dp[i] |= dp[i - length] && s1.equals(s.substring(i - length, i));
if (dp[i]) break;
}
}
return dp[s.length()];
}
//回溯+记忆化搜索
int[] memo;
public boolean wordBreak2(String s, List<String> wordDict) {
memo = new int[s.length() + 1];
Arrays.fill(memo, -1);
return dfs(s, wordDict, s.length());
}
public boolean dfs(String s, List<String> wordDict, int i) {
if (i == 0) {
memo[i] = 1;
return true;
}
if (memo[i] != -1) {
return memo[i] == 1;
}
boolean flag = false;
for (String s1 : wordDict) {
int length = s1.length();
if(i>=length)flag |= dfs(s, wordDict, i - length)&&s1.equals(s.substring(i-length,i));
if (flag) {
memo[i] = 1;
return flag;
}
}
memo[i] = 0;
return false;
}
}

View File

@ -0,0 +1,50 @@
package com.markilue.leecode.hot100.second;
import com.markilue.leecode.listnode.ListNode;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-09 11:36
*@Description:
* TODO 力扣141 环形链表:
*@Version: 1.0
*/
public class T53_141_HasCycle {
//快慢指针判断一个链表是否有环
public boolean hasCycle(ListNode head) {
if (head == null) {
return false;
}
ListNode fake = new ListNode();
fake.next = head;
ListNode slow = fake.next;
ListNode fast = fake.next.next;
while (fast != null && fast.next != null && fast != slow) {
fast = fast.next.next;
slow = slow.next;
}
return fast != slow;
}
//优秀写法
public boolean hasCycle1(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) return true;
}
return false;
}
}