分割数组
给定一个数组 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]
解题思路
对于数组left,它的第一个成员就是nums[0]
,然后我们需要遍历nums数组中的每个数字,当发现遍历的这个数字nums[i]
大于nums[0]
的时候,则表示这个数字暂时可能不属于数组left。那么当发现遍历的这个数字nums[i]小于或等于nums[0]
的时候,则可以判断出这个数字一定是属于数组left的。
根据题目可知left 中的每个元素都小于或等于 right 中的每个元素所以我们需要一个变量leftMax来保存数组left中的最大数字,以及下标index,用于划分数组left和数组right。只要发现遍历的数字小于或等于leftMax时,我们就可以通过移动index来划分出新的数组left。当我们遍历完所有的nums数组中的数字之后,index指向的位置就是数组left的最后一个元素的位置。那么数组left的长度就等于index + 1
具体步骤如下:
- 第一步:初始化一个index,用于存储当前索引,max用于与存储最大值,先令第一个元素等于最大值;leftMax用于存储左边数组最大值
- 第二步:遍历数组,for循环内判断
leftMax
与当前元素的大小 - 第三步:如果左边的最大值小于nums后面的每一项,则令max为【max和nums[i]比较】的最大值
- 第四步:如果
leftMax > nums[i]
则index存储当前下标,并且令leftMax = max
- 第五步:返回index+1为左边数组的长度
var partitionDisjoint = function(nums) { let index = 0, max = nums[0], leftMax = max; for (let i = 0; i < nums.length; i++) { if (leftMax > nums[i]) { index = i; leftMax = max; } else { max = Math.max(max, nums[i]); } } return index + 1; };