2024.9.14 Python,差分法解决区间加法,消除游戏,压缩字符串

1.区间加法

假设你有一个长度为 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 Solution:
    def getModifiedArray(self, length: int, updates: List[List[int]]) -> List[int]:
        res=[0]*length
        while updates:
            (x,y,z)=updates.pop()
            for i in range(x,y+1):
                res[i]+=z
        return res

我这个代码等于每次都要遍历所以遍历太多次了

class Solution:
    def getModifiedArray(self, length: int, updates: List[List[int]]) -> List[int]:
        difference=[0]*length
        for (x,y,z) in updates:
            difference[x]+=z
            if y+1<length:
                difference[y+1]-=z
        for i in range(1,length):
            difference[i]+=difference[i-1]
        return difference

用差分思想就可以少遍历一些元素,最后统一计算。差分思想就是后面的比前面的多多少,然后最后一个元素的下一个就减掉,然后最后统一计算。

2.消除游戏

列表 arr 由在范围 [1, n] 中的所有整数组成,并按严格递增排序。请你对 arr 应用下述算法:
从左到右,删除第一个数字,然后每隔一个数字删除一个,直到到达列表末尾。
重复上面的步骤,但这次是从右到左。也就是,删除最右侧的数字,然后剩下的数字每隔一个删除一个。
不断重复这两步,从左到右和从右到左交替进行,直到只剩下一个数字。
给你整数 n ,返回 arr 最后剩下的数字。
示例 1:
输入:n = 9
输出:6
解释:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr = [2, 4, 6, 8]
arr = [2, 6]
arr = [6]
示例 2:
输入:n = 1
输出:1

class Solution:
    def lastRemaining(self, n: int) -> int:
        res=[0]*n
        for i in range(n):
            res[i]=i+1
        while len(res)>1:
            i=0
            while i<len(res):
                res.pop(i)
                i+=1
            if len(res)==1:
                break
            i=len(res)-1
            while i>=0:
                res.pop(i)
                i-=2
        return res[0]

这个代码模拟了这个过程但是超时了,所以最后还是要使用数学大法

class Solution:
	def lastRemaining(self,n:int)->int:
		head=1
		step=1
		left=True
		while n>1:
			if left or n%2!=0:
				head+=step
			step*=2
			n//=2
			left= not left
		return head		

大概逻辑是,每次向左循环的时候,都要向后移一位,移动的step是由循环次数决定的,第一次加1,第二次加21.第三次加22,以此类推,然后向左移动的时候,如果数列此时是奇数的,那么就head一定会右移,如果是偶数,那么这一次循环不需要右移,只需要加step就可以了,别忘了给n地板除2,同时给left取反,目的是区分左行还是右行。

3.压缩字符串

给你一个字符数组 chars ,请使用下述算法压缩:
从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 :
如果这一组长度为 1 ,则将字符追加到 s 中。
否则,需要向 s 追加字符,后跟这一组的长度。
压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 10 或 10 以上,则在 chars 数组中会被拆分为多个字符。
请在 修改完输入数组后 ,返回该数组的新长度。
你必须设计并实现一个只使用常量额外空间的算法来解决此问题。
示例 1:
输入:chars = [“a”,“a”,“b”,“b”,“c”,“c”,“c”]
输出:返回 6 ,输入数组的前 6 个字符应该是:[“a”,“2”,“b”,“2”,“c”,“3”]
解释:“aa” 被 “a2” 替代。“bb” 被 “b2” 替代。“ccc” 被 “c3” 替代。
示例 2:
输入:chars = [“a”]
输出:返回 1 ,输入数组的前 1 个字符应该是:[“a”]
解释:唯一的组是“a”,它保持未压缩,因为它是一个字符。
示例 3:
输入:chars = [“a”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”]
输出:返回 4 ,输入数组的前 4 个字符应该是:[“a”,“b”,“1”,“2”]。
解释:由于字符 “a” 不重复,所以不会被压缩。“bbbbbbbbbbbb” 被 “b12” 替代。

class Solution:
    def compress(self, chars: List[str]) -> int:
        stack=""
        nums=1
        res=[]
        numlist=[]
        for char in chars:
            if not stack:
                stack+=char
            elif char==stack:
                nums+=1
            elif char!=stack:
                res.append(stack)
                if nums!=1:
                    nums=str(nums)
                    for num in nums:
                        numlist.append(num)
                    res+=numlist
                    numlist=[]
                    nums=1
                stack=char
        res.append(char)        
        if nums!=1:
            nums=str(nums)
            for num in nums:
                numlist.append(num)
            res+=numlist
        for i in range(len(res)):
            if len(chars)>i:
                chars[i]=res[i] 
            else:
                chars.append(res[i] )
        return len(res)     

自用代码,臭的像一坨。明天写一下双指针的办法。

你可能感兴趣的:(python,游戏,开发语言,算法,力扣)