Skip to content

Latest commit

 

History

History

0915.Partition Array into Disjoint Intervals

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

English Version

题目描述

给定一个数组 nums ,将其划分为两个连续子数组 left 和 right, 使得:

  • left 中的每个元素都小于或等于 right 中的每个元素。
  • left 和 right 都是非空的。
  • left 的长度要尽可能小。

在完成这样的分组后返回 left 的 长度 

用例可以保证存在这样的划分方法。

 

示例 1:

输入:nums = [5,0,3,8,6]
输出:3
解释:left = [5,0,3],right = [8,6]

示例 2:

输入:nums = [1,1,1,0,6,12]
输出:4
解释:left = [1,1,1,0],right = [6,12]

 

提示:

  • 2 <= nums.length <= 105
  • 0 <= nums[i] <= 106
  • 可以保证至少有一种方法能够按题目所描述的那样对 nums 进行划分。

解法

方法一:前缀最大值 + 后缀最小值

划分后的两个子数组要满足题目要求,需要保证“数组前缀最大值”小于等于“数组后缀最小值”。

因此,我们可以先预处理出数组的后缀最小值,记录在 mi 数组中。

然后从前往后遍历数组,维护数组前缀的最大值 mx,当遍历到某个位置时,如果数组前缀最大值小于等于数组后缀最小值,那么当前位置就是划分的分界点,直接返回即可。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 nums 的长度。

class Solution:
    def partitionDisjoint(self, nums: List[int]) -> int:
        n = len(nums)
        mi = [inf] * (n + 1)
        for i in range(n - 1, -1, -1):
            mi[i] = min(nums[i], mi[i + 1])
        mx = 0
        for i, v in enumerate(nums, 1):
            mx = max(mx, v)
            if mx <= mi[i]:
                return i
class Solution {
    public int partitionDisjoint(int[] nums) {
        int n = nums.length;
        int[] mi = new int[n + 1];
        mi[n] = nums[n - 1];
        for (int i = n - 1; i >= 0; --i) {
            mi[i] = Math.min(nums[i], mi[i + 1]);
        }
        int mx = 0;
        for (int i = 1; i <= n; ++i) {
            int v = nums[i - 1];
            mx = Math.max(mx, v);
            if (mx <= mi[i]) {
                return i;
            }
        }
        return 0;
    }
}
class Solution {
public:
    int partitionDisjoint(vector<int>& nums) {
        int n = nums.size();
        vector<int> mi(n + 1, INT_MAX);
        for (int i = n - 1; ~i; --i) mi[i] = min(nums[i], mi[i + 1]);
        int mx = 0;
        for (int i = 1; i <= n; ++i) {
            int v = nums[i - 1];
            mx = max(mx, v);
            if (mx <= mi[i]) return i;
        }
        return 0;
    }
};
func partitionDisjoint(nums []int) int {
	n := len(nums)
	mi := make([]int, n+1)
	mi[n] = nums[n-1]
	for i := n - 1; i >= 0; i-- {
		mi[i] = min(nums[i], mi[i+1])
	}
	mx := 0
	for i := 1; i <= n; i++ {
		v := nums[i-1]
		mx = max(mx, v)
		if mx <= mi[i] {
			return i
		}
	}
	return 0
}