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;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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