刷题的日常-分割数组

76 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情

刷题的日常-2022年10月24号

一天一题,保持脑子清爽

分割数组

来自leetcode的 915 题,题意如下:

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

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

在完成这样的分组后返回left的长度。
用例可以保证存在这样的划分方法。

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给出一个数组
  • 要求我们对数组分成两个部分
  • 第二部分所有的数字 要大于等于 第一部分的所有数值
  • 返回第一部分的大小

做题思路

要让左边的数 小于等于 第二部分的数,那么数组里的最小值一定要划分在第一部分,所以我们要先找出最小值位置。以最小值的位置作为划分,分出左右两个部分,这个时候我们还需要检查划分出来的两个部分中,第二部分 有没有比 第一部分的最大值还要小的值,如果有,还要将当前值作为划分才能满足需求,步骤如下:

  • 先找出最小值的分界线
  • 寻找的过程中顺便记录最小值分界线的最大值
  • 找出最小值分界线之后,以分界线为开始往后扫描
  • 找出比分界线左边最大值还要小的值
  • 找到之后作为新的分界点,在这过程中也需要更新分界线的最大值
  • 重复以上步骤知道数组最后
  • 返回分界点 + 1即为结果

代码实现

代码实现如下:

public class Solution {
    public int partitionDisjoint(int... nums) {
        int post = nums.length - 1;
        int min = 0, max = 0, minMax = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] < nums[min]) {
                minMax = max;
            }
            min = nums[i] < nums[min] ? i : min;
            max = nums[max] < nums[i] ? i : max;
        }
        max = minMax;
        for (int i = min; i < nums.length; i++) {
            max = nums[max] < nums[i] ? i : max;
            if (nums[i] >= nums[minMax]) {
                continue;
            }
            max = nums[max] < nums[i] ? i : max;
            minMax = max;
            min = i;
        }
        return min + 1;
    }
}

5ffd79e3619424ff21e724129b1be8a.jpg