力扣第186场周赛总结

这是第二次参赛,还是只AC了第一道题目。加油,其他题解参考了很多大神的写法。
1、题目描述:分割字符串的最大得分
https://leetcode-cn.com/problems/maximum-score-after-splitting-a-string/
在这里插入图片描述
在这里插入图片描述
题解:
暴力法:

class Solution:
    def maxScore(self, s: str) -> int:
        m = 0
        for i in range(0,len(s)):
            count1 ,count2 = 0,0
            if i == 0:
                if s[i] == '0':
                    count1 += 1
                for j in range(i+1,len(s)):
                    if s[j] == '1':
                        count2 += 1                
            elif i == len(s) -1:
                if s[len(s) -1] == '1':
                    count2 += 1
                for k in range(i):               
                    if s[k] == '0':
                        count1 += 1
            else:
                for k in range(i):               
                    if s[k] == '0':
                        count1 += 1
                for j in range(i,len(s)):
                    if s[j] == '1':
                        count2 += 1
            if count1 + count2 > m:
                m =count1 + count2
        return m

优化:

class Solution:
    def maxScore(self, s: str) -> int:
        #先遍历一遍,求1的个数
        n = len(s)
        s0,s1 = 0,0
        for i in range(n):
            if s[i] == '1':
                s1 += 1
        #再次遍历,遇到0,s0+1;遇到1,s1-1;并且每次比较(res,s0+s1)
        res = 0
        for i in range(n-1):
            if s[i] == '0':
                s0 += 1
            if s[i] == '1':
                s1 -= 1
            res = max(res,s0+s1)
        return res

2、可获得的最大点数
题目描述:
https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards/
在这里插入图片描述
在这里插入图片描述
题解:

class Solution:
    def maxScore(self, cardPoints: List[int], k: int) -> int:
        if k >= len(cardPoints):
            return sum(cardPoints)
        if k ==0:
            return 0
        n = len(cardPoints)
        res = 0
        for i in range(0,k+1):            
            s = 0
            for l in range(0,i):
                s += cardPoints[l] 
            for j in range(n-k+i,n):
                s += cardPoints[j]
            if s > res:
                res = s
        return res
            

但超出了时间限制
优化:滑动窗口法

class Solution:
    def maxScore(self, cardPoints: List[int], k: int) -> int:
        #前后共k的窗口大小
        #先计算前k个窗口的大小
        win,mx,lens = 0,0,len(cardPoints)
        for i in range(k):
            win += cardPoints[i]
        #然后移动这个窗口,寻找最大值
        mx = max(mx,win)
        for i in range(k):
            win -= cardPoints[k -i -1]
            win += cardPoints[lens -1 -i]
            mx = max(mx,win)
        return mx

3、对角线遍历 II
题目描述:
https://leetcode-cn.com/problems/diagonal-traverse-ii/
可对比498对角线遍历

在这里插入图片描述
题解:
同一个方向上的下标和一样

class Solution:
    def findDiagonalOrder(self, nums: List[List[int]]) -> List[int]:
        sub_result = []
        for i in range(len(nums)):
            for j in range(len(nums[i])):
                if i + j >= len(sub_result):
                    sub_result.append([])
                sub_result[i + j].append(nums[i][j])

        result = []
        for sub in sub_result:
            result += sub[::-1]
        return result
class Solution(object):
    def findDiagonalOrder(self, nums):
        a,s,m=[(0,0)],[nums[0][0]],len(nums)
        while a:
            b=[]
            for i,j in a:
                for ii,jj in (i+1,j),(i,j+1):
                    if ii<m and jj<len(nums[ii]) and nums[ii][jj]!=-1:
                        s.append(nums[ii][jj])
                        b.append((ii,jj))
                        nums[ii][jj]=-1
            a=b
        return s
class Solution:
    def findDiagonalOrder(self, nums: List[List[int]]) -> List[int]:
        from collections import defaultdict
        group = defaultdict(list)
        for r, row in enumerate(nums):
            #print(r, row)
            for c, num in enumerate(row):
                ss = r + c
                group[ss].append(num)
        res = []
        #print(group)
        for _, s in enumerate(group.values()):
            p = s[::-1]
            for i in p:
                res.append(i)
        return res         

上面的算法的运行结果如下(注意两个print,是为了理解collections.defaultdict)
在这里插入图片描述

4、带限制的子序列和
题目描述:
https://leetcode-cn.com/problems/constrained-subset-sum/
结合239题滑动窗口最大值

在这里插入图片描述
在这里插入图片描述
题解:

class Solution:
    def constrainedSubsetSum(self, nums: List[int], k: int) -> int:
        n = len(nums)
        dp = nums[:]
        dp[0] = nums[0]
        res = nums[0]
        s = [(nums[0], 0)]
        for i in range(1, len(nums)):
            dp[i] = max(dp[i], s[0][0] + nums[i])
            while s and s[-1][0] <= dp[i]:
                s.pop()
            s.append((dp[i], i))
            if s[0][1] <= i - k:
                s.pop(0)
            res = max(res, dp[i])
        return res

#作者:wangdh15
#链接:https://leetcode-cn.com/problems/constrained-subset-sum/solution/dpdan-diao-zhan-you-hua-xiang-jie-by-wangdh15/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值