首页 > 其他分享 >LeetCode | 370 RangeAddition

LeetCode | 370 RangeAddition

时间:2024-08-02 23:50:37浏览次数:16  
标签:nums int numsA RangeAddition 差分 数组 diff 370 LeetCode

https://github.com/dolphinmind/datastructure/tree/datastructure-array-02

分析

数组本身的递归性,差分数组的不变性和可逆性,在left索引上对当前及后续所有元素产生影响,在right+1索引上进行反操作,消除这种影响,再进行还原即可

  • 数组本身具有递归性
  • 差分数组性质:对于任何常数c,如果将原始数组所有元素加上c,则差分数组不变;从一个数组可以唯一确定其差分数组,反之亦然

利用上面的两个前提中,我们来看

int nums       = {8,  2,  6,  3,  1};
int difference = {8, -6,  4, -3, -2};
// 还原[1, 4]部分的差分 numsA[1] = numsA[1], numsA[2] = numsA[1] + difference[2]
int numsA      = {8, -6, -2, -5, -7};

nums[1] = numsA[0] + numsA[1] = 2
nums[2] = numsA[0] + numsA[2] = 6
nums[3] = numsA[0] + numsA[3] = 3
nums[4] = numsA[0] + numsA[4] = 1

// numsA[0] 相当于对子差分数组进行整体+8

从上述的例子中发现了什么规律没有?差分数组的子类也始终属于差分,差分数组进行数组还原的过程,每个元素都对其后续所有元素具有同步影响,对差分数组的头部加或减一个常数,就相当于把原数组从头部开始直到后面所有元素进行了相应的操作,因为什么?原数组整体增加/减少一个常量对差分数组本身毫无影响

所以在差分数组中[left, right]

  • left索引下的数组元素上进行常数增减操作,就是对left索引之后的原数组所有数据元素进行对应操作
  • right索引后续数组元素要消除这种传递性,就需要进行反操作

主类

Difference工具类

package com.github.dolphinmind.array.utils;

/**
 * @author dolphinmind
 * @ClassName Difference
 * @description 差分数组
 *              性质:对于任何常数c,如果将原始数组的所有元素加上c,则差分数组不变
 *              即arr[i] -> arr[i] + c 不改变 diff数组
 * @date 2024/8/2
 */

public class Difference {

    private int[] diff;

    public Difference(int[] nums) {
        assert nums.length > 0;
        diff = new int[nums.length];

        // 初始值保持不变
        diff[0] = nums[0];
        for (int i = 1; i < nums.length; i++) {
            diff[i] = nums[i] - nums[i-1];
        }
    }

    /**
     * 给闭区间[i,j]增加val(可以是负数)
     */
    public void increment(int i, int j, int val) {
        diff[i] += val;
        // 边界判断
        if (j + 1 < diff.length) {
            diff[j+1] -= val;
        }
    }

    /**
     * 返回复原数组
     * @return
     */
    public int[] result() {
        int[] res = new int[diff.length];
        res[0] = diff[0];

        for (int i = 1; i < diff.length; i++) {
            res[i] = res[i-1] + diff[i];
        }

        return res;
    }
}

RangeAddition类

package com.github.dolphinmind.array;

import com.github.dolphinmind.array.utils.Difference;

/**
 * @author dolphinmind
 * @ClassName RangeAddition
 * @description 370 区间加法
 *
 * 输入: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]
 * 输出: [-2,0,3,5,3]
 * @date 2024/8/2
 */

public class RangeAddition {

    public int[] getModifiedArray(int length, int[][] updates) {

        // nums 初始化为全0
        int[] nums = new int[length];

        Difference difference = new Difference(nums);

        for (int[] update : updates) {
            int left     = update[0];
            int right    = update[1];
            int constant = update[2];
            difference.increment(left, right, constant);
        }

        return difference.result();
    }
}

测试类

package com.github.dolphinmind.array;

import org.junit.Test;

/**
 * @author dolphinmind
 * @ClassName RangeAdditionTest
 * @description
 * @date 2024/8/2
 */

public class RangeAdditionTest {

    @Test
    public void test_getModifiedArray() {
        int length = 5;
        int[][] updates = {{1, 3, 2}, {2, 4, 3}, {0, 2, -2}};

        int[] result = new RangeAddition().getModifiedArray(length, updates);

        printArray(result);

    }

    /**
     * @description 打印数组
     * @param nums
     */

    public void printArray(int[] nums) {
        System.out.println();

        System.out.print("[");
        for (int item : nums) {
            System.out.print(item + " ");
        }
        System.out.print("]");
    }
}

标签:nums,int,numsA,RangeAddition,差分,数组,diff,370,LeetCode
From: https://www.cnblogs.com/dolphinmind/p/18339898

相关文章

  • LeetCode 热题 HOT 100 (015/100)【宇宙最简单版】
    【栈】No.0155最小栈【中等】......
  • leetcode 2181.合并零之间的结点
    1.题目要求:/***Definitionforsingly-linkedlist.*structListNode{*intval;*structListNode*next;*};*/structListNode*mergeNodes(structListNode*head){structListNode*cur=head;intcount=0;//1.遍历结......
  • leetcode 2181.合并零之间的结点
    1.题目要求:/***Definitionforsingly-linkedlist.*structListNode{*intval;*structListNode*next;*};*/structListNode*mergeNodes(structListNode*head){structListNode*cur=head;intcount=0;//1.遍历结......
  • LeetCode | 303 RangeSumQueryImmutable
    https://github.com/dolphinmind/datastructure/tree/datastructure-array-02分析所求解的区间[left,right]具有连续性,执行常规for循环计算,[0,left-1]的区间元素累加和与[0,right]的区间元素累加和,有重复的运算区间[0,left)。累加和与长跑比赛其实一致,求取[left,right]区......
  • 【代码随想录训练营第42期 Day17打卡 二叉树Part5-LeetCode 654.最大二叉树 617.合并
    目录一、做题心得二、题目与题解题目一:654.最大二叉树题目链接题解:递归题目二:617.合并二叉树题目链接题解:递归(前序遍历)题目三:617.合并二叉树题目链接题解:BFS层序遍历 题目四:98.验证二叉搜索树题目链接题解:递归(中序遍历)三、小结一、做题心得今天是代码随想......
  • LeetCode 152 乘积最大子数组
    题目描述给你一个整数数组nums,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。测试用例的答案是一个32位整数。思路这一题用普通的连续子数组思路求解时有一个问题:子问题的最优解不一定是总体的最优局部解。也就是不满足最优......
  • 【leetcode232:用栈实现队列】
    leetcode232:用栈实现队列题目:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现MyQueue类:voidpush(intx)将元素x推到队列的末尾intpop()从队列的开头移除并返回元素intpeek()返回队列开头的元素booleanemp......
  • LeetCode | 59 SpiralMatrixII
    主类https://github.com/dolphinmind/datastructure/tree/datastructure-array-02循环不变量原则,保证问题边界的逻辑一致性(从二分法的启发)初始位置旋转圈数奇偶性四条边的边界逻辑offsetpackagecom.github.dolphinmind.array;/***@authordolphinmind*@C......
  • [Leetcode]SQL语句
    groupby182.查找重复的电子邮箱SQLSchemaPandasSchema表:Person+-------------+---------+|ColumnName|Type|+-------------+---------+|id|int||email|varchar|+-------------+---------+id是该表的主键(具有唯一值的列)。此......
  • 二叉搜索树,Map,Set,LeetCode刷题
    二叉搜索树,Map,Set1.二叉搜索树2.二叉搜索树的模拟实现1.1插入操作1.2查找操作1.3删除操作3.二叉搜索树时间复杂度分析4.TreeMap和TreeSet5.Map5.1Map的常用方法5.2Map.Entry<K,V>6.Set6.1Set的常用方法LeetCode刷题1.二叉搜索树与双向链表1.二叉搜......