leetcode刷题的差分数组技巧【Python】

leetcode刷题的差分数组技巧【Python】

2 差分数组
差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减。常规思路是用for循环实现,时间复杂度为O(n)。用差分数组可将时间复杂度降为O(1)。具体做法为先构建差分数组diff,diff[i]=nums[i]-nums[i-1]

nums=[8,2,6,3,1]
diff =[nums[0]]
for i in range(1,len(nums)):
    diff.append(nums[i]-nums[i-1])
print(diff)

通过差分数组也可以反推出原始数组nums

res = [diff[0]]
for i in range(1,len(diff)):
    res.append(diff[i]+res[i-1])
    
print(res)

如果对nums[i:j+1]的元素全部+3,那么只要diff[i] += 3,然后diff[j+1] -= 3即可。

370.区间加法(中等)

假设你有一个长度为 n 的数组,初始情况下所有的数字均为 0,你将会被给出 k个更新的操作。

其中,每个操作会被表示为一个三元组:[startIndex, endIndex, inc],你需要将子数组 A[startIndex … endIndex](包括 startIndex 和 endIndex)增加 inc。

请你返回 k 次操作后的数组。

示例:

输入: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]

输出: [-2,0,3,5,3]

解释:

初始状态: [0,0,0,0,0]

进行了操作 [1,3,2] 后的状态: [0,2,2,2,0]

进行了操作 [2,4,3] 后的状态: [0,2,5,5,3]

进行了操作 [0,2,-2] 后的状态: [-2,0,3,5,3]

class Difference(object):
    def __init__(self,nums):
        self.nums=nums
        
    def diff_gen(self):
        """生成差分数组"""
        diff=[self.nums[0]]
        for i in range(1,len(self.nums)):
            diff.append(self.nums[i]-self.nums[i-1])
        return diff
    
    def nums_res(self,i,j,val):
        """还原数组"""
        diff = self.increment(i,j,val)
        res =[diff[0]]
        for i in range(1,len(diff)):
            res.append(diff[i]+res[i-1])
        return res
    
    def increment(self,i,j,val):
        """区间加法"""
        diff = self.diff_gen()
        diff[i] += val
        if len(diff)>j+1:
            diff[j+1] -= val
        return diff
    
if __name__=='__main__':
    updates = [[1,3,2],[2,4,3],[0,2,-2]]
    length = 5
    nums=[0]*length
    d = Difference(nums)
    for i in range(len(updates)):
        diff=d.nums_res(updates[i][0],updates[i][1],updates[i][2])
        d = Difference(diff)
        print(diff)

简单解法:

class Solution(object):
    def getModifiedArray(self, length, updates):
        """
        :type length: int
        :type updates: List[List[int]]
        :rtype: List[int]
        """
        res = [0 for _ in range(length + 1)]
        
        for update in updates:
            start, end, inc = update[0], update[1], update[2]
            res[start] += inc
            res[end + 1] -= inc
        
        for i in range(1, length):
            res[i] += res[i - 1]
            
        return res[:-1]
    
if __name__=='__main__':
    length=5
    updates = [[1,3,2],[2,4,3],[0,2,-2]]
    d = Solution()
    print(d.getModifiedArray(length,updates))

1109.航班预订统计(中等)

这里有 n 个航班,它们分别从 1 到 n 进行编号。

有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firsti 和 lasti )的 每个航班 上预订了 seatsi 个座位。

请你返回一个长度为 n 的数组 answer,其中 answer[i] 是航班 i 上预订的座位总数。

示例 1:

输入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5

输出:[10,55,45,25,25]

解释:

航班编号 1 2 3 4 5

预订记录 1 : 10 10

预订记录 2 : 20 20

预订记录 3 : 25 25 25 25

总座位数: 10 55 45 25 25

因此,answer = [10,55,45,25,25]

1 2 3 4 5 6 7 8 9

示例 2:

输入:bookings = [[1,2,10],[2,2,15]], n = 2

输出:[10,25]

解释:

航班编号 1 2

预订记录 1 : 10 10

预订记录 2 : 15

总座位数: 10 25

因此,answer = [10,25]

#直接套用上述框架,注意航班编号是从1开始
class Difference(object):
    def __init__(self,nums):
        self.nums=nums
        
    def diff_gen(self):
        """生成差分数组"""
        diff=[self.nums[0]]
        for i in range(1,len(self.nums)):
            diff.append(self.nums[i]-self.nums[i-1])
        return diff
    
    def nums_res(self,i,j,val):
        """还原数组"""
        diff = self.increment(i,j,val)
        res =[diff[0]]
        for i in range(1,len(diff)):
            res.append(diff[i]+res[i-1])
        return res
    
    def increment(self,i,j,val):
        """区间加法"""
        diff = self.diff_gen()
        diff[i] += val
        if len(diff)>j+1:
            diff[j+1] -= val
        return diff
    
if __name__=='__main__':
    bookings = [[1,2,10],[2,3,20],[2,5,25]]
    n = 5
    nums=[0]*n
    d = Difference(nums)
    
    for i in range(len(bookings)):
        diff=d.nums_res(bookings[i][0]-1,bookings[i][1]-1,bookings[i][2])
        d = Difference(diff)
        print(diff)

1094.拼车(中等)

假设你是一位顺风车司机,车上最初有 capacity 个空座位可以用来载客。由于道路的限制,车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向,你可以将其想象为一个向量)。

这儿有一份行程计划表 trips[][],其中 trips[i] = [num_passengers, start_location, end_location] 包含了你的第 i 次行程信息:

必须接送的乘客数量;
乘客的上车地点;
以及乘客的下车地点。
这些给出的地点位置是从你的 初始 出发位置向前行驶到这些地点所需的距离(它们一定在你的行驶方向上)。

请你根据给出的行程计划表和车子的座位数,来判断你的车是否可以顺利完成接送所用乘客的任务(当且仅当你可以在所有给定的行程中接送所有乘客时,返回 true,否则请返回 false)。

示例 1:

输入:trips = [[2,1,5],[3,3,7]], capacity = 4

输出:false

示例 2:

输入:trips = [[2,1,5],[3,3,7]], capacity = 5

输出:true

示例 3:

输入:trips = [[2,1,5],[3,5,7]], capacity = 3

输出:true

示例 4:

输入:trips = [[3,2,7],[3,7,9],[8,3,9]], capacity = 11

输出:true

提示:

你可以假设乘客会自觉遵守 “先下后上” 的良好素质

trips.length <= 1000

trips[i].length == 3

1 <= trips[i][0] <= 100

0 <= trips[i][1] < trips[i][2] <= 1000

1 <= capacity <= 100000

#直接套用上述框架,注意航班编号是从1开始
class Difference(object):
    def __init__(self,nums):
        self.nums=nums
        
    def diff_gen(self):
        """生成差分数组"""
        diff=[self.nums[0]]
        for i in range(1,len(self.nums)):
            diff.append(self.nums[i]-self.nums[i-1])
        return diff
    
    def nums_res(self,i,j,val):
        """还原数组"""
        diff = self.increment(i,j,val)
        res =[diff[0]]
        for i in range(1,len(diff)):
            res.append(diff[i]+res[i-1])
        return res
    
    def increment(self,i,j,val):
        """区间加法"""
        diff = self.diff_gen()
        diff[i] += val
        if len(diff)>j+1:
            diff[j+1] -= val
        return diff
    
def solution(arr,capacity):
    nums=[0]*1000
    d = Difference(nums)
    for i in range(len(arr)):
        diff=d.nums_res(arr[i][1],arr[i][2]-1,arr[i][0])
        d = Difference(diff)
    #print(diff)
    for j in diff:
        if j>capacity:
            return False
        else:
            continue
    return True

if __name__=='__main__':

    trips = [[2,1,5],[3,3,7]]
    capacity = 4
    print( solution(trips,capacity))
    
    trips = [[2,1,5],[3,3,7]] 
    capacity = 5
    print( solution(trips,capacity))
    
    trips = [[2,1,5],[3,5,7]]
    capacity = 3
    print( solution(trips,capacity))
    
    trips = [[3,2,7],[3,7,9],[8,3,9]]
    capacity = 11
    print( solution(trips,capacity))

简单解法:

def solution(arr,capacity):
    nums=[0]*1000
    for i in range(len(arr)):
        for j in range(arr[i][1],arr[i][2]):
            nums[j] += arr[i][0]
            
    #print(diff)
    for x in nums:
        if x>capacity:
            return False
        else:
            continue
    return True

if __name__=='__main__':

    trips = [[2,1,5],[3,3,7]]
    capacity = 4
    print( solution(trips,capacity))
    
    trips = [[2,1,5],[3,3,7]] 
    capacity = 5
    print( solution(trips,capacity))
    
    trips = [[2,1,5],[3,5,7]]
    capacity = 3
    print( solution(trips,capacity))
    
    trips = [[3,2,7],[3,7,9],[8,3,9]]
    capacity = 11
    print( solution(trips,capacity))
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值