zoukankan      html  css  js  c++  java
  • 181. 差分数组学习

    1.查分数组

    1.首先名字看起来很高大上其实呢就是前一项减后一项, 不用怕
    举个例子: 
    list1 = [2, 5, 4, 9, 7, 10, 0]
    list1 = [0, 2, 5, 4, 9, 7, 10, 0]  # 最前面补一个零(因为第一项没有前一个元素)
    diff_list = []
    for i in range(1, len(list1)):
        diff_list.append(list1[i] - list1[i-1])  # 前一项减去后一项
    print(diff_list)  
    # 结果就是这个样子, 他能干嘛呢? 发现没有如果给diff_list计算前缀和刚好就是原数组
    diff_list = [2, 3, -1, 5, -2, 3, -10]
    
    2.计算前缀和(可能你不相信我说前缀和就是他的原数组没关系,算一遍)
    size = len(diff_list)
    list2 = [0 for _ in range(size +1)]
    for i in range(1, size + 1):  # 这里是为了计算前缀和数组
        list2[i] = list2[i-1] + diff_list[i-1]
    print(list2)
    [0, 2, 5, 4, 9, 7, 10, 0]  你看看他想不想list1也就是原数组
    这个时候你明白了差分数组的其中一个作用了把?计算前缀和还原数组
    
    3.产品听需求了,我们需要给
    	1. [1, 4]的数值全部加上3
        2. 上面条件的基础上[3, 5] 减去5
    是不是感觉很简单? 遍历一遍加上去就可以了,但是如果如果数量级比较大1e5你1000ms可以过去么? 很不幸我在力扣里面超时了.
    
    这时候就需要利用差分数组的性质了: 将原始数组中元素同时加上或者减掉某个数,那么他们的差分数组其实是不会变化的
    没事不懂咋就举例子: 
    list1 =     [0, 2, 5, 4, 9, 7, 10, 0]  原数组
    diff_list = [2, 3, -1, 5, -2, 3, -10]  差分数组
    
    [1, 4]的数值全部加上3
    如果我们给差分数组1索引位置元素+3, 4+1=5所以位置-3会造成什么?
    diff_list = [2, 3+3, -1, 5, -2, 3-3, -10]
    
    # 说话你们不信, 直接看代码, 结果[0, 2, 8, 7, 12, 10, 10, 0], 看到了什么[1,4]+3了, 其他数据没影响是不是很完美.(0是我们加的辅助数字不需要管)
    diff_list = [2, 3+3, -1, 5, -2, 3-3, -10]
    size = len(diff_list)
    list2 = [0 for _ in range(size +1)]
    for i in range(1, size + 1):  # 这里是为了计算前缀和数组
        list2[i] = list2[i-1] + diff_list[i-1]
    print(list2)  # [0, 2, 8, 7, 12, 10, 10, 0]
    
    上面条件的基础上[3, 5] 减去5 # 经过上面我相信你已经明白了,如果需要修改[x,y]位置元素大小只需要给x位置+对应数字, y+1位置-对应数组即可(相信减法你可以理解),进行第二个条件
    diff_list = [2, 3+3, -1, 5-5, -2, 3-3, -10+5]
    size = len(diff_list)
    list2 = [0 for _ in range(size +1)]
    for i in range(1, size + 1):  # 这里是为了计算前缀和数组
        list2[i] = list2[i-1] + diff_list[i-1]
    print(list2)  # [0, 2, 8, 7, 12, 10, 10, 0]
    [0, 2, 8, 7, 12, 10, 10, 0]  # 条件1结果
    [0, 2, 8, 7, 7, 5, 5, 0]  # 条件2结果
    
    # 防止你们不相信, 我暴力的修改也给出来, 如下
    list1 = [2, 5, 4, 9, 7, 10, 0]
    size = len(list1)
    for i in range(size):
        if 1 <= i <= 4:
            list1[i] += 3
    
        if 3 <= i <= 5:
            list1[i] -= 5
    print(list1)   # [2, 8, 7, 7, 5, 5, 0]
    
    
    4.总结3写成代码diff_list差分数组  [x, y]位置加上同样大小的数m
    diff[x] += m
    diff[y+1] -= 1 # y+1需要小于数组长度n, len(diff_list)
    注意 只能是区间元素同时增加或减少相同的数的情况才能用
    
    5.实践开始,
    

    1.题目1: HDU-1556 Color the Ball

    说实话第一次遇到查分数组相关问这个气球搞得我很懵逼, 但是看了大佬的代码一下在就明白了?
    我把这题根据力扣的题目改了一下:(还是返回气球总共修改了几次)
    其中n表示气球数量, balls数组放置每次涂改颜色的区间(前后都包含)给你看个例子就好了
    例1:
    n = 3
    balls = [[1, 1], [2,3], [3,3]]
    结果 [1, 1, 1]
    例2:
    n = 3
    balls = [[1, 1], [1,2], [1,3]]
    结果 [3, 2, 1]  # 这个结果其实就是最后的差分数组,他记录了每个位置对应的气球修改的次数
    代码如下:
    def func(balls, n):
            a = [0 for _ in range(n+1)]  # 结果数组
            b = [0 for _ in range(n+1)]  # 差分数组
    
            for i in range(len(balls)):
                x, y = balls[i]
                b[x] += 1  # 1其实就是每次修改一遍
                if y < n:
                    b[y+1] -= 1
    
            for i in range(1, n+1):
                a[i] = a[i-1] + b[i]  # 前缀和
    
            return a[1:]
    

    1.题目二: 1109. 航班预订统计

    这个题很题目一很类似, 上面统计修改次数, 这个题目统计座位数目. 只不过给区间加上了权重,也就是座位数
    class Solution(object):
        def corpFlightBookings(self, bookings, n):
            """
            https://blog.csdn.net/qq_44786250/article/details/100056975  参考这个学习查分数组
            航班编号        1   2   3   4   5
            预订记录 1 :   10  10
            预订记录 2 :       20  20
            预订记录 3 :       25  25  25  25
            总座位数:      10  55  45  25  25
            :type bookings: List[List[int]]
            :type n: int
            :rtype: List[int]
            """
            a = [0 for _ in range(n+1)]
            b = [0 for _ in range(n+1)]
    
            for i in range(len(bookings)):
                x, y, w = bookings[i]
                b[x] += w  # 同样的代码加上权重就好了
                if y < n:
                    b[y+1] -= w
    
            for i in range(1, n+1):
                a[i] = a[i-1] + b[i]
    
            return a[1:]
    
  • 相关阅读:
    mvc判断用户使用的手机或电脑或平板访问程序的方法
    把数据复制到剪切板
    wenform控件fileupload上传文件
    <input type="file">上传文件
    一般处理程序中删除文件
    Ajax中用layer弹出层并刷新页面的方法
    Yii CDBCriteria常用方法(转)
    PHP错位类型及屏蔽方式
    php网站高并发 大流量访问的处理及解决方法
    高并发量网站解决方案
  • 原文地址:https://www.cnblogs.com/liuzhanghao/p/15209236.html
Copyright © 2011-2022 走看看