Given an array `A`, partition it into two (contiguous) subarrays `left` and `right` so that:

  • Every element in left is less than or equal to every element in right.
  • left and right are non-empty.
  • left has the smallest possible size.

Return the length of left after such a partitioning.  It is guaranteed that such a partitioning exists.

Example 1:

Input: [5,0,3,8,6]
Output: 3
Explanation: left = [5,0,3], right = [8,6]

Example 2:

Input: [1,1,1,0,6,12]
Output: 4
Explanation: left = [1,1,1,0], right = [6,12]

Note:

  1. 2 <= A.length <= 30000
  2. 0 <= A[i] <= 10^6
  3. It is guaranteed there is at least one way to partition A as described.

这道题说是给了一个数组A,让我们分成两个相邻的子数组 left 和 right,使得 left 中的所有数字小于等于 right 中的,并限定了每个输入数组必定会有这么一个分割点,让返回数组 left 的长度。这道题并不算一道难题,当然最简单并暴力的方法就是遍历所有的分割点,然后去验证左边的数组是否都小于等于右边的数,这种写法估计会超时,这里就不去实现了。直接来想优化解法吧,由于分割成的 left 和 right 数组本身不一定是有序的,只是要求 left 中的最大值要小于等于 right 中的最小值,只要这个条件满足了,一定就是符合题意的分割。left 数组的最大值很好求,在遍历数组的过程中就可以得到,而 right 数组的最小值怎么求呢?其实可以反向遍历数组,并且使用一个数组 backMin,其中 backMin[i] 表示在范围 [i, n-1] 范围内的最小值,有了这个数组后,再正向遍历一次数组,每次更新当前最大值 curMax,这就是范围 [0, i] 内的最大值,通过 backMin 数组快速得到范围 [i+1, n-1] 内的最小值,假如 left 的最大值小于等于 right 的最小值,则 i+1 就是 left 的长度,直接返回即可,参见代码如下:


解法一:

class Solution {
public:
int partitionDisjoint(vector<int>& A) {
int n = A.size(), curMax = INT_MIN;
vector<int> backMin(n, A.back());
for (int i = n - 2; i >= 0; --i) {
backMin[i] = min(backMin[i + 1], A[i]);
}
for (int i = 0; i < n - 1; ++i) {
curMax = max(curMax, A[i]);
if (curMax <= backMin[i + 1]) return i + 1;
}
return 0;
}
};

下面来看论坛上的主流解法,只需要一次遍历即可,并且不需要额外的空间,这里使用三个变量,partitionIdx 表示分割点的位置,preMax 表示 left 中的最大值,curMax 表示当前的最大值。思路是遍历每个数字,更新当前最大值 curMax,并且判断若当前数字 A[i] 小于 preMax,说明这个数字也一定是属于 left 数组的,此时整个遍历到的区域应该都是属于 left 的,所以 preMax 要更新为 curMax,并且当前位置也就是潜在的分割点,所以 partitionIdx 更新为i。由于题目中限定了一定会有分割点,所以这种方法是可以得到正确结果的,参见代码如下:


解法二:

class Solution {
public:
int partitionDisjoint(vector<int>& A) {
int partitionIdx = 0, preMax = A[0], curMax = preMax;
for (int i = 1; i < A.size(); ++i) {
curMax = max(curMax, A[i]);
if (A[i] < preMax) {
preMax = curMax;
partitionIdx = i;
}
}
return partitionIdx + 1;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/915

参考资料:

https://leetcode.com/problems/partition-array-into-disjoint-intervals/

https://leetcode.com/problems/partition-array-into-disjoint-intervals/discuss/175945/Java-one-pass-7-lines

https://leetcode.com/problems/partition-array-into-disjoint-intervals/discuss/175842/JAVA-EASIEST-SIMPLEST

[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)

[LeetCode] 915. Partition Array into Disjoint Intervals 分割数组为不相交的区间的更多相关文章

  1. 【LeetCode】915. Partition Array into Disjoint Intervals 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/partitio ...

  2. 【leetcode】915. Partition Array into Disjoint Intervals

    题目如下: 解题思路:题目要求的是在数组中找到一个下标最小的index,使得index左边(包括自己)子序列的最大值小于或者等于右边序列的最小值.那么我们可以先把数组从最左边开始到数组最右边所有子序列 ...

  3. [Swift]LeetCode915.将分区数组分成不相交的间隔 | Partition Array into Disjoint Intervals

    Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element ...

  4. Partition Array into Disjoint Intervals LT915

    Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element ...

  5. Partition Array into Disjoint Intervals

    2020-02-10 22:16:50 问题描述: 问题求解: 解法一:MultiSet O(nlog) 看了下数据规模,第一个想到的是multiset,肯定可以ac的,就直接敲了出来. public ...

  6. [LeetCode] 548. Split Array with Equal Sum 分割数组成和相同的子数组

    Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies fol ...

  7. leetcode@ [352] Data Stream as Disjoint Intervals (Binary Search & TreeSet)

    https://leetcode.com/problems/data-stream-as-disjoint-intervals/ Given a data stream input of non-ne ...

  8. [LeetCode] 352. Data Stream as Disjoint Intervals 分离区间的数据流

    Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...

  9. [LeetCode] Split Array with Equal Sum 分割数组成和相同的子数组

    Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies fol ...

随机推荐

  1. php explode容易犯的错误

    php explode容易犯的错误 <pre> $pos = strpos($v, 'Controller'); if (is_numeric($pos)) { $kongzhiqifeg ...

  2. pandas使用大全--数据与处理

    1.首先导入pandas库,一般都会用到numpy库,所以我们先导入备用: import numpy as np import pandas as pd 导入CSV或者xlsx文件: df = pd. ...

  3. 『大 树形dp』

    大 Description 滑稽树上滑稽果,滑稽树下你和我,滑稽树前做游戏,滑稽多又多.树上有 n 个节点,它们构成了一棵树,每个节点都有一个滑稽值. 一个大的连通块是指其中最大滑稽值和最小滑稽值之差 ...

  4. springboot拦截器拦了静态资源css,js,png,jpeg,svg等等静态资源

    1.在SpringBoot中自己写的拦截器,居然把静态资源也拦截了,导致了页面加载失败. package com.bie.config; import com.bie.component.MyLoca ...

  5. ASP.NET MVC 中的过滤器

    这里用实例说明各种过滤器的用法,有不对的地方还请大神指出,共同探讨. 1. ActionFilter 方法过滤器: 接口名为 IActionFilter ,在控制器方法调用前/后执行. 在新建的MVC ...

  6. minggw 安装

    windows上如果没有安装 visual studio, 也就是俗称的vs, 在安装一些带有c或者c++代码的Python模块的时候, 会报错Unable to find vcvarsall.bat ...

  7. 面试官常问的Nginx的几个问题

    1.什么是Nginx? Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3 ...

  8. 数据解析模块BeautifulSoup简单使用

    一.准备环境: 1.准备测试页面test.html <html> <head> <title> The Dormouse's story </title> ...

  9. 关联mysql失败_Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon' 时区错误

    时区错误,MySQL默认的时区是UTC时区,比北京时间晚8个小时. 所以要修改mysql的时长 在mysql的命令模式下,输入: set global time_zone='+8:00'; 再次连接成 ...

  10. SpirngBoot整合Spring-data-JPA

    0.引言 使用SpringBoot data jpa技术相比mybatis是比较难的,这里只给出整合方法 1.引入SpringBoot data jpa <!--JPA依赖--> < ...