分割数组得到最小绝对差
3698. 分割数组得到最小绝对差 - 力扣(LeetCode)
Solution
一次遍历,记录以每个元素结尾的最长递增子数组的长度以及最长递减子数组的长度,同时记录前缀和数组。
有了上一次遍历得到的结果之后,再遍历一次,枚举分割位置,这样就可以很轻松的判断是否满足递增和递减的条件,并且根据前缀和可以很容易的求和。
class Solution {
public:const long long inf = 1e11;long long splitArray(vector<int>& nums) {int n = nums.size();if (n == 2)return abs(nums[0] - nums[1]);vector<int> f1(n, 1); // 递增vector<int> f2(n, 1); // 递减vector<long long> sum_up(n + 1, 0);sum_up[0] = 0;for (int i = 1; i < n; ++i) {if (nums[i] > nums[i - 1])f1[i] = f1[i - 1] + 1;if (nums[i] < nums[i - 1])f2[i] = f2[i - 1] + 1;}for (int i = 1; i <= n; ++i) {sum_up[i] = nums[i - 1] + sum_up[i - 1];}long long ans = inf;for (int i = 0; i < n - 1; ++i) {// i=0,n=3,f1[0]==1&&f2[2]>=3-0-1if (f1[i] == i + 1 && f2[n - 1] >= n - i - 1) {long long s1 = sum_up[i + 1];long long s2 = sum_up[n] - sum_up[i + 1];// cout<<s1<<" "<<s2<<endl;ans = min(ans, abs(s1 - s2));}}if (ans != inf)return ans;elsereturn -1;}
};