【差分数组】个人练习-Leetcode-3229. Minimum Operations to Make Array Equal to Target

题目链接:https://leetcode.cn/problems/minimum-operations-to-make-array-equal-to-target/description/

题目大意:给出两个数组nums[]target[],可以对nums[]数组进行这样两种操作

  • 给某个区间内的子列全加1
  • 给某个区间内的子列全减1

求让nums[]target[]相等的最小操作次数。

思路:实际上就是让a[] = target[] - nums[]这个数组全为0,操作同样适用在a[]上。考虑到这样一个事实:对于数组的某个区间的统一操作,相当于对于差分数组的两个区间端点做操作。因此构造a[]的差分数组d[]。那么对a[i]a[j-1]的操作,就相当于对d[i]d[j]进行操作。比如对下面这个数组a[]的0~2个元素减去1后,d[0]d[3]发生了改变。

a: 1 1 1 -2			->	a: 0 0 0 -2 
d: 1 0 0 -3 2		->	d: 0 0 0 -2 2

并且对于d[]的改变,必然是某个d[i] += 1,某个d[j] -= 1。因此对于a[]某个区间进行操作,就相当于对d[]的两个端点,一个+1,一个-1。

因为最终会将a[]变为全0,此时d[]也全为0,那么就要对d[]进行一对对进行加减。然而反过来考虑,d[]从全0变为别的样子的时候,也是一对对加减上去的,因此实际上d[]中的元素之和一定为0。

那么只需要找正的元素个数即可,这就是最佳的方案。非最佳的方案对应着的是,在d[]的某个元素上+1又-1,这样必然会让操作次数增多。

完整代码

class Solution {
public:
    long long minimumOperations(vector<int>& nums, vector<int>& target) {
        int n = nums.size();
        for (int i = 0; i < n; i++) {
            nums[i] = target[i] - nums[i];
        }
        vector<int> diff(n+1, 0);
        diff[0] = nums[0];
        for (int i = 1; i < n; i++) {
            diff[i] = nums[i] - nums[i-1];
        }
        diff[n] = -nums[n-1];

        long long ans = 0;
        for (int i = 0; i <= n; i++) {
            ans += max(diff[i], 0);
        }

        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值