【力扣每日一题】915.分割数组

915.分割数组

题目描述

给定一个数组 nums ,将其划分为两个连续子数组 left 和 right, 使得:
left 中的每个元素都小于或等于 right 中的每个元素。
left 和 right 都是非空的。
left 的长度要尽可能小。
在完成这样的分组后返回 left 的 长度
用例可以保证存在这样的划分方法。

示例图片

在这里插入图片描述

解题思路

方法:首先根据题目描述,我们很快的能发现:
1.分割数组的那个位置一定在整个数组的最小值和最大值之间。
2.最小值一定在最大值的左边。
3.left数组的最大值总是比right数组的最小值要小。

因此,不妨先找到数组最大值和最小值的位置,同时,找到最小值位置之前的最大值,和最大值位置之后的最小值(有点绕,好好理解)。例如示例1,最小值是0,最大值是8, 最小值之前的最大值是5,最大值之后的最小值是6。

然后,在最小值和最大值位置之间,我们利用类似快速排序算法的方式,分别向左和向右遍历,知道两个遍历指针相邻,则找到分割数组的位置。

代码

int partitionDisjoint(int* nums, int numsSize){
    int min=nums[0]; int max=nums[0]; //整个数组的最大值和最小值
    int l_max=nums[0]; int r_min=nums[numsSize-1]; //左右数组的最大值和最小值
    int i,j;
    int low=0; int high=numsSize-1;
    if(numsSize<=2){ return 1; }
    //找整个数组最大值和最小值的位置
    for(i=1;i<numsSize;i++){
        if(min>=nums[i]){ min=nums[i]; low=i; }
        if(max<=nums[i]){ max=nums[i]; high=i; }
    }
    //找最小值位置之前的最大值
    for(i=1;i<=low;i++){
        if(l_max<nums[i]){ l_max=nums[i]; }
    }
    for(i=numsSize-1;i>=high;i--){
        if(r_min>nums[i]){ r_min=nums[i]; }
    }
    //遍历
    while(low!=(high-1)){
        while(l_max<=r_min && low!=(high-1)){
            high--;
            if(r_min>nums[high]){ r_min=nums[high]; }
        }
        if(l_max>r_min){ r_min=nums[++high]; }
        while(l_max<=r_min && low!=(high-1)){
            low++;
            if(l_max<nums[low]){ l_max=nums[low]; }
        }
    }

    return low+1;
}

提交结果

在这里插入图片描述
用的方法比较笨,没有优化,有更好的方法欢迎补充。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值