侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 675 篇文章
  • 累计创建 128 个标签
  • 累计收到 26 条评论

目 录CONTENT

文章目录

【遍历】分割数组

GabrielxD
2022-10-24 / 0 评论 / 0 点赞 / 281 阅读 / 400 字
温馨提示:
本文最后更新于 2022-11-04,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

915. 分割数组


给定一个数组 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 <= 10^5
  • 0 <= nums[i] <= 10^6
  • 可以保证至少有一种方法能够按题目所描述的那样对 nums 进行划分。

解题

方法一:三次遍历

思路

代码

class Solution {
    public int partitionDisjoint(int[] nums) {
        int n = nums.length;
        int[] leftMax = new int[n], rightMin = new int[n];
        leftMax[0] = nums[0];
        rightMin[n - 1] = nums[n - 1];
        for (int i = 1, j = n - 2; i < n; ++i, j = n - i - 1) {
            leftMax[i] = Math.max(leftMax[i - 1], nums[i]);
            rightMin[j] = Math.min(rightMin[j + 1], nums[j]);
        }
        for (int i = 0; i < n - 1; ++i) {
            if (leftMax[i] <= rightMin[i + 1]) return i + 1;
        }
        return -1;
    }
}

方法二:两次遍历

思路

代码

class Solution {
    public int partitionDisjoint(int[] nums) {
        int n = nums.length;
        int[] mins = new int[n];
        mins[n - 1] = nums[n - 1];
        for (int i = n - 2; i >= 0 ; --i) mins[i] = Math.min(mins[i + 1], nums[i]);
        for (int i = 0, max = nums[0]; i < n - 1; max = Math.max(max, nums[++i])) {
            if (max <= mins[i + 1]) return i + 1;
        }
        return -1;
    }
}

方法三:一次遍历

思路

代码

0

评论区