leecode更新
This commit is contained in:
parent
357262888d
commit
4080e880b3
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.markilue.leecode.hot100.second;
|
package com.markilue.leecode.hot100.second;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -18,6 +20,12 @@ import java.util.HashSet;
|
||||||
*/
|
*/
|
||||||
public class T50_128_LongestConsecutive {
|
public class T50_128_LongestConsecutive {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {100, 4, 200, 1, 3, 2};
|
||||||
|
System.out.println(longestConsecutive2(nums));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 思路:用hashset记录所有,记录最大的值
|
* 思路:用hashset记录所有,记录最大的值
|
||||||
|
|
@ -95,5 +103,32 @@ public class T50_128_LongestConsecutive {
|
||||||
return result;
|
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;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue