LeetCode 915. 分割数组
题目描述
思路分析
解法一:前缀最大 + 后缀最小(推荐)
核心思路:
leftMax[i]表示0..i的最大值,rightMin[i]表示i..n-1的最小值。- 找到最小的
i满足leftMax[i] <= rightMin[i+1]。- 分割点为
i + 1。
复杂度分析:
- 时间复杂度:O(n),其中 n 表示数组长度。
- 空间复杂度:O(n),需要两个辅助数组。
class Solution {
public int partitionDisjoint(int[] nums) {
int n = nums.length;
int[] leftMax = new int[n];
int[] rightMin = new int[n];
leftMax[0] = nums[0];
for (int i = 1; i < n; i++) {
leftMax[i] = Math.max(leftMax[i - 1], nums[i]);
}
rightMin[n - 1] = nums[n - 1];
for (int i = n - 2; i >= 0; i--) {
rightMin[i] = Math.min(rightMin[i + 1], nums[i]);
}
for (int i = 0; i < n - 1; i++) {
if (leftMax[i] <= rightMin[i + 1]) {
return i + 1;
}
}
return n;
}
}
func partitionDisjoint(nums []int) int {
n := len(nums)
leftMax := make([]int, n)
rightMin := make([]int, n)
leftMax[0] = nums[0]
for i := 1; i < n; i++ {
if nums[i] > leftMax[i-1] {
leftMax[i] = nums[i]
} else {
leftMax[i] = leftMax[i-1]
}
}
rightMin[n-1] = nums[n-1]
for i := n - 2; i >= 0; i-- {
if nums[i] < rightMin[i+1] {
rightMin[i] = nums[i]
} else {
rightMin[i] = rightMin[i+1]
}
}
for i := 0; i < n-1; i++ {
if leftMax[i] <= rightMin[i+1] {
return i + 1
}
}
return n
}
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 769. 最多能完成排序的块 | 中等 | 前缀最大 |
| 768. 最多能完成排序的块 II | 困难 | 前缀最大 |
| 238. 除自身以外数组的乘积 | 中等 | 前后缀 |
| 915. 分割数组 | 中等 | 前后缀 |
| 1438. 绝对差不超过限制的最长连续子数组 | 中等 | 双端队列 |
本博客所有文章除特别声明外,均采用
CC BY-NC-SA 4.0
许可协议,转载请注明出处!