915.分割数组
给定一个数组 nums ,将其划分为两个连续子数组 left 和 right, 使得:
-
left 中的每个元素都小于或等于 right 中的每个元素。
-
left 和 right 都是非空的。
-
left 的长度要尽可能小。
在完成这样的分组后返回 left 的 长度 。
用例可以保证存在这样的划分方法。
思路1(×):时间复杂度o(n^2),空间复杂度o(1)超出时间限制。
缺点在于每一次都计算了left和right中的最值,导致时间超出。
class Solution { public: int max1(int left, int right, vector<int> nums) { int max_res = 0; for (int i = left; i <= right; i++) { if (nums[i] > max_res) max_res = nums[i]; } return max_res; } int min1(int left, int right, vector<int> nums) { int min_res = 1e6; for (int i = left; i <= right; i++) { if (nums[i] < min_res) min_res = nums[i]; } return min_res; } int partitionDisjoint(vector<int>& nums) { for (int i = 0; i < nums.size(); i++) { if (max1(0, i, nums) <= min1(i+1, nums.size()-1, nums)) { return i + 1; } } return 0; } };
思路2:时间复杂度o(n),空间复杂度o(n)
用数组存储了后right的最值,不用再每次都去找最值了
class Solution { public: int partitionDisjoint(vector<int>& nums) { int n = nums.size(); vector<int> minRight(n); minRight[n - 1] = nums[n - 1]; for (int i = n - 2; i >= 0; i--) { minRight[i] = min(nums[i], minRight[i + 1]); } int maxLeft = 0; for (int i = 0; i < n - 1; i++) { maxLeft = max(maxLeft, nums[i]); if (maxLeft <= minRight[i + 1]) { return i + 1; } } return 0; } };