问题描述:
给定一个数组 nums ,将其划分为两个连续子数组 left 和 right, 使得:
- left 中的每个元素都小于或等于 right 中的每个元素。
- left 和 right都是非空的。
- left 的长度要尽可能小。
在完成这样的分组后返回 left 的 长度 。
用例可以保证存在这样的划分方法。
样例如下:
代码如下:方法一使用暴力,方法二使用空间换时间的方法
public class PartitionDisjoint {
public static int getLeftMax(int[] nums,int index){//返回index左侧的最大值
int max = nums[0];
for (int i = 0; i < index; i++) {
if (nums[i]>max) max = nums[i];
}
return max;
}
public static int getRightMin(int[] nums,int index){//返回index右侧的最小值
int min = nums[index];
for (int i = index; i < nums.length; i++) {
if (nums[i]<min) min = nums[i];
}
return min;
}
//暴力破解
public static int partitionDisjoint(int[] nums) {
int ans = 1;
for (int i = 1; i <nums.length ; i++) {
int left = getLeftMax(nums,i);
int right = getRightMin(nums,i);
if (left<=right){
ans = i;
break;
}
}
return ans;
}
// 方法二 空间换时间
public static int partitionDisjoint1(int[] nums) {
int ans = 1;
int[] leftMax = new int[nums.length]; //记录左侧最大值的数组
leftMax[0] = nums[0];
int[] rightMin = new int[nums.length]; //记录右侧最小值的数组
rightMin[nums.length-1] = nums[nums.length-1];
for (int i = 1; i <nums.length ; i++) {
if (nums[i]>leftMax[i-1]) {//若当前值大于当前已存在的最大值,则更新这个最大值
leftMax[i] = nums[i];
}else leftMax[i] = leftMax[i-1];//若当前值没有大于当前已存在的最大值,则为上一个值
}
for (int i = nums.length-2; i >=0 ; i--) {
if (nums[i]<rightMin[i+1]) {//若当前值小于当前已存在的最小值,则更新这个最小值
rightMin[i] = nums[i];
}else rightMin[i] = rightMin[i+1];//若当前值没有小于当前已存在的最小值,则为上一个值
}
for (int i = 0; i <nums.length-1 ; i++) {
int left = leftMax[i];
int right = rightMin[i+1];
if (left<=right){
ans = i+1;
break;
}
}
return ans;
}
public static void main(String[] args) {
System.out.println(partitionDisjoint1(new int[]{1,1,1,0,6,12}));
System.out.println(partitionDisjoint1(new int[]{5,0,3,8,6}));
System.out.println(partitionDisjoint1(new int[]{90,47,69,10,43,92,31,73,61,97}));
System.out.println(partitionDisjoint1(new int[]{5,0,3,8,6}));
}
}
结果如下: