From dbd0be69e80022b4842266d817a0a7a7f8af6859 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Wed, 16 Jul 2025 20:50:07 +0800 Subject: [PATCH] =?UTF-8?q?7.16=20=E8=82=A1=E7=A5=A8=E4=B9=B0=E5=8D=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/dynamic_programming/MaxProfit.java | 1 + .../java/dynamic_programming/MaxProfit2.java | 5 +- .../java/dynamic_programming/MaxProfit3.java | 1 + src/main/java/greedy/MaxProfit.java | 14 ++- src/main/java/greedy/MaxProfit2.java | 9 +- src/main/java/greedy/MaxProfit3.java | 40 ++++---- src/main/java/实现类功能/MedianFinder.java | 96 +++++++++++++++++++ 7 files changed, 141 insertions(+), 25 deletions(-) create mode 100644 src/main/java/实现类功能/MedianFinder.java diff --git a/src/main/java/dynamic_programming/MaxProfit.java b/src/main/java/dynamic_programming/MaxProfit.java index 7a08dbf..7564c04 100644 --- a/src/main/java/dynamic_programming/MaxProfit.java +++ b/src/main/java/dynamic_programming/MaxProfit.java @@ -14,6 +14,7 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/ */ //需要琢磨 +//二刷会做 public class MaxProfit { public int maxProfit(int[] prices) { int n = prices.length; diff --git a/src/main/java/dynamic_programming/MaxProfit2.java b/src/main/java/dynamic_programming/MaxProfit2.java index d6a8785..72d05f3 100644 --- a/src/main/java/dynamic_programming/MaxProfit2.java +++ b/src/main/java/dynamic_programming/MaxProfit2.java @@ -5,17 +5,18 @@ package dynamic_programming; * 描述:给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 * 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 * 返回 你能获得的 最大 利润 。 - *
+ * 示例 1: * 输入:prices = [7,1,5,3,6,4] * 输出:7 * 解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。 * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。 * 最大总利润为 4 + 3 = 7 。 - *
+
* 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
*/
//不会dp做法
+//二刷会做
public class MaxProfit2 {
// 由于允许多次交易,「今天买入」的收益要在「昨天不持有」的基础上减去今天的价格;「今天卖出」的收益要在「昨天持有」的基础上加上今天的价格。
// dp[i][0]:第i天持有股票时的最大收益
diff --git a/src/main/java/dynamic_programming/MaxProfit3.java b/src/main/java/dynamic_programming/MaxProfit3.java
index 29fb937..65d0f2c 100644
--- a/src/main/java/dynamic_programming/MaxProfit3.java
+++ b/src/main/java/dynamic_programming/MaxProfit3.java
@@ -16,6 +16,7 @@ package dynamic_programming;
* 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/
*/
//不会
+//二刷不会
public class MaxProfit3 {
/**
* 一天一共就有五个状态,
diff --git a/src/main/java/greedy/MaxProfit.java b/src/main/java/greedy/MaxProfit.java
index 078f07d..fbea2e1 100644
--- a/src/main/java/greedy/MaxProfit.java
+++ b/src/main/java/greedy/MaxProfit.java
@@ -14,8 +14,20 @@ package greedy;
* 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
*/
- //第一次做没想出来,每次都假设是今天卖出,然后求今天之前的历史最低点。
+//第一次做没想出来,每次都假设是今天卖出,然后求今天之前的历史最低点。
+//二刷会做
public class MaxProfit {
+ public int maxProfit2(int[] prices) {
+ int maxprofit=0;
+ int minprice=prices[0];
+ for (int i = 1; i < prices.length; i++) {
+ if(prices[i]>minprice)maxprofit=Math.max(maxprofit,prices[i]-minprice);
+ else minprice=prices[i];
+ }
+ return maxprofit;
+ }
+
+
public int maxProfit(int prices[]) {
int minprice = Integer.MAX_VALUE;
int maxprofit = 0;
diff --git a/src/main/java/greedy/MaxProfit2.java b/src/main/java/greedy/MaxProfit2.java
index fdaf883..3aaed55 100644
--- a/src/main/java/greedy/MaxProfit2.java
+++ b/src/main/java/greedy/MaxProfit2.java
@@ -14,8 +14,15 @@ package greedy;
* 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
*/
-
+//二刷会做
public class MaxProfit2 {
+ public int maxProfit2(int[] prices) {
+ int maxProfit=0;
+ for (int i = 1; i < prices.length; i++) {
+ maxProfit+=Math.max(prices[i]-prices[i-1],0);
+ }
+ return maxProfit;
+ }
//考虑复杂了!
public int maxProfit1(int[] prices) {
int n = prices.length, profit = 0;
diff --git a/src/main/java/greedy/MaxProfit3.java b/src/main/java/greedy/MaxProfit3.java
index 40e449e..4c1f19a 100644
--- a/src/main/java/greedy/MaxProfit3.java
+++ b/src/main/java/greedy/MaxProfit3.java
@@ -16,12 +16,13 @@ package greedy;
* 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/
*/
//不会 困难题
-
+//二刷不会
public class MaxProfit3 {
/**
* 举个小例子 prices = [1, 5, 2, 6](共 4 天):
- *
- * 左半段你能算出 left = [0, 4, 4, 5]。
+ * left[i] 表示在第 0 天到第 i 天范围内,最多做一笔交易能获得的最优利润
+ * 左半段:left = [0, 4, 4, 5]。
+ * right[i] 表示「从第 i 天到最后一天」这一段区间内,最多做一笔交易能拿到的最大利润
* 右半段:
* 以 i=2(价格 2)为起点:未来最高是 6,利润 = 6−2 = 4。
* 以 i=1(价格 5)为起点:未来最高同样 6,利润 = 6−5 = 1。
@@ -33,33 +34,30 @@ public class MaxProfit3 {
*/
public int maxProfit(int[] prices) {
int n = prices.length;
- if (n < 2) return 0; // (1)
+ if (n < 2) return 0;
// 1. left[i]: 0…i 天内最多一笔交易的最优收益
int[] left = new int[n];
- int minPrice = prices[0]; // (2)
+ int minPrice = prices[0];
for (int i = 1; i < n; i++) {
- minPrice = Math.min(minPrice, prices[i]); // (3) 更新最低买入价
- left[i] = Math.max(left[i - 1], // (4) 选「不做新交易」或「今天卖出」
- prices[i] - minPrice);
+ minPrice = Math.min(minPrice, prices[i]);
+ left[i] = Math.max(left[i - 1], prices[i] - minPrice);
}
// 2. right[i]: i…n-1 天内最多一笔交易的最优收益
- int[] right = new int[n + 1]; // (5) 右边界额外留 1,用于 i=n-1 时访问
- int maxPrice = prices[n - 1]; // (6)
- for (int i = n - 1; i >= 0; i--) {
- maxPrice = Math.max(maxPrice, prices[i]); // (7) 更新最高卖出价
- right[i] = Math.max(right[i + 1], // (8) 选「不做新交易」或「今天买入后再卖出」
- maxPrice - prices[i]);
+ int[] right = new int[n];
+ right[n - 1] = 0; // 只有最后一天,无交易可能
+ int maxPrice = prices[n - 1];
+ for (int i = n - 2; i >= 0; i--) {
+ maxPrice = Math.max(maxPrice, prices[i]);
+ right[i] = Math.max(right[i + 1], maxPrice - prices[i]);
}
- // 3. 枚举切分点:第一笔结束在 i,第二笔从 i+1 开始
- int ans = 0;
- for (int i = -1; i < n; i++) { // (9)
- int leftProfit = (i >= 0) ? left[i] : 0; // (10)
- int rightProfit = (i + 1 < n) ? right[i + 1] : 0; // (11)
- ans = Math.max(ans, leftProfit + rightProfit); // (12)
+ // 3. 合并两段:写法 B(更简洁)
+ int ans = right[0]; // 只做一笔(当作第二笔)
+ for (int i = 0; i < n - 1; i++) {
+ ans = Math.max(ans, left[i] + right[i + 1]);
}
- return ans; // (13)
+ return ans;
}
}
diff --git a/src/main/java/实现类功能/MedianFinder.java b/src/main/java/实现类功能/MedianFinder.java
new file mode 100644
index 0000000..92fa0c0
--- /dev/null
+++ b/src/main/java/实现类功能/MedianFinder.java
@@ -0,0 +1,96 @@
+package 实现类功能;
+
+import java.util.Collections;
+import java.util.PriorityQueue;
+
+/**
+ * 题目: 295. 数据流的中位数 (partitionMedianFinder)
+ * 描述:中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
+ * 例如 arr = [2,3,4] 的中位数是 3 。
+ * 例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5 。
+ * 实现 MedianFinder 类:
+ * MedianFinder() 初始化 MedianFinder 对象。
+
+ * void addNum(int num) 将数据流中的整数 num 添加到数据结构中。
+
+ * double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。
+
+ 示例 1:
+ 输入
+ ["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
+ [[], [1], [2], [], [3], []]
+ 输出
+ [null, null, null, 1.5, null, 2.0]
+
+ 解释
+ MedianFinder medianFinder = new MedianFinder();
+ medianFinder.addNum(1); // arr = [1]
+ medianFinder.addNum(2); // arr = [1, 2]
+ medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
+ medianFinder.addNum(3); // arr[1, 2, 3]
+ medianFinder.findMedian(); // return 2.0
+
+ * 链接:https://leetcode.cn/problems/palindrome-partitioning/
+ */
+//困难题,二刷不会
+
+/**
+ * 使用一个小顶堆 A(存储较大的一半)和一个大顶堆 B(存储较小的一半),并在每次插入后保持以下不变式:
+ * A 的大小 = B 的大小,或 A 的大小 = B 的大小 + 1
+ * A 中始终保存「较大的一半」元素,长度为 N/2(N 为偶数)或 (N+1)/2(N 为奇数)。
+ * B 中始终保存「较小的一半」元素,长度为 N/2(N 为偶数)或 (N–1)/2(N 为奇数)。
+ */
+public class MedianFinder {
+ // 小顶堆 A:保存较大的一半元素
+ private PriorityQueue