Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[pull] master from wisdompeak:master #321

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
pull merged 3 commits into AlgorithmAndLeetCode:master from wisdompeak:master
Jun 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class Solution {
public:
int countPartitions(vector<int>& nums, int k) {
int n = nums.size();
long M = 1e9+7;
nums.insert(nums.begin(), 0);

vector<long>dp(n+1);
vector<long>presum(n+1);
dp[0] = 1;
presum[0] = 1;

deque<int>dq1;
deque<int>dq2;
int left = 1;
for (int i=1; i<=n; i++) {
int x = nums[i];
while (!dq1.empty() && nums[dq1.back()]<x) {
dq1.pop_back();
}
dq1.push_back(i);
while (!dq2.empty() && nums[dq2.back()]>x) {
dq2.pop_back();
}
dq2.push_back(i);

while (left <= i && nums[dq1.front()] - nums[dq2.front()] > k) {
if (dq1.front()==left) dq1.pop_front();
if (dq2.front()==left) dq2.pop_front();
left++;
}
// Any valid parition that ends at left-1, left, left+1, ..., i-1 is good.

dp[i] = presum[i-1] - (left>=2?presum[left-2]:0);
presum[i] = presum[i-1] + dp[i];

dp[i] = (dp[i] + M) % M;
presum[i] = (presum[i] + M) % M;
}

return dp[n];
}
};
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
### 3578.Count-Partitions-With-Max-Min-Difference-at-Most-K

我们很容易想到令dp[i]表示以i为最后一段区间的结尾,可以得到的切割方案。此时我们需要考虑最后一段的起点位置j可以在哪里。

题目条件中"区间最大值与区间最小值的差",很容易提示我们可以用deque来分别求区间的最大值和最小值。更具体地,当我们从nums[0]开始,不断加入元素,直至将nums[i]纳入区间时,我们可以得到此时区间的最大值a和最小值b:如果a-b>k,那么意味着区间太长,起点位置应该往右移动。这是因为区间越大,就越容易得到更大的a和更小的b,必然有更大的差值。区间越小,a-b的值就会越小,而且这是一个单调的过程。于是我们调整左端点j右移,每移动一次的过程中,我们查看一下nums[j]的退出是否会影响保存区间最大值和最小值的两个deque(因为我们知道当前最大值或最小值必然是deque的首元素)。直至我们将左端点移动到L的位置,意味着区间[L:i]恰好满足最大值与最小值之差小于k。

以上说明区间[L:i]是一个合法的切分,同理更小的区间[L+1:i],[L+2:i]...都是满足条件的切分。既然确定了最后一个区间的切法,那么就有`dp[i] = dp[L-1]+dp[L]+dp[L+1]...+dp[i-1]` 显然,我们会用一个DP的前缀和数组presum来辅助,即`dp[i] = presum[i-1]-presum[L-2]`.

记得得到上述的dp[i]之后,就可以同样更新presum[i]。

以1-index考虑的话,最终的结果就是dp[n]。
1 change: 1 addition & 0 deletions Readme.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@
[2398.Maximum-Number-of-Robots-Within-Budget](https://github.com/wisdompeak/LeetCode/tree/master/Deque/2398.Maximum-Number-of-Robots-Within-Budget) (H-)
[2762.Continuous-Subarrays](https://github.com/wisdompeak/LeetCode/tree/master/Deque/2762.Continuous-Subarrays) (M+)
[2969.Minimum-Number-of-Coins-for-Fruits-II](https://github.com/wisdompeak/LeetCode/tree/master/Deque/2969.Minimum-Number-of-Coins-for-Fruits-II) (H-)
[3578.Count-Partitions-With-Max-Min-Difference-at-Most-K](https://github.com/wisdompeak/LeetCode/tree/master/Deque/3578.Count-Partitions-With-Max-Min-Difference-at-Most-K) (H-)

#### [Priority Queue](https://github.com/wisdompeak/LeetCode/tree/master/Priority_Queue)
[004.Median-of-Two-Sorted-Arrays](https://github.com/wisdompeak/LeetCode/tree/master/Priority_Queue/004.Median-of-Two-Sorted-Arrays) (H)
Expand Down

AltStyle によって変換されたページ (->オリジナル) /