这是第二次参赛,还是只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/