目录
分割字符串的最大得分
给你一个由若干 0 和 1 组成的字符串 s ,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。
「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1 的数量。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-score-after-splitting-a-string
示例
输入:s = “011101”
输出:5
解释: 将字符串 s 划分为两个非空子字符串的可行方案有:
左子字符串 = “0” 且 右子字符串 = “11101”,得分 = 1 + 4 = 5
左子字符串 = “01” 且 右子字符串 = “1101”,得分 = 1 + 3 = 4
左子字符串 = “011” 且 右子字符串 = “101”,得分 = 1 + 2 = 3
左子字符串 = “0111” 且 右子字符串 = “01”,得分 = 1 + 1 = 2
左子字符串 = “01110” 且 右子字符串 = “1”,得分 = 2 + 1 = 3
我的思路
利用Python的冒号分割和count()函数。
看漏要求左右字串都是非空子集而被罚时。
因为count()是O(n)的,故整体是O(n**2)的,但未超时
我的代码
|
|
别人的思路
先统计字符串中1的个数,然后从左往右遍历,当为1时,1的个数减1,0的个数加1,每次求和留最大值。
时间复杂度降低为O(n)
别人的代码
|
|
可获得的最大点数
几张卡牌 排成一行,每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。
每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 k 张卡牌。
你的点数就是你拿到手中的所有卡牌的点数之和。
给你一个整数数组 cardPoints 和整数 k,请你返回可以获得的最大点数。
提示:
- 1 <= cardPoints.length <= 10^5
- 1 <= cardPoints[i] <= 10^4
- 1 <= k <= cardPoints.length
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards
示例
输入:cardPoints = [1,2,3,4,5,6,1], k = 3
输出:12
解释:第一次行动,不管拿哪张牌,你的点数总是 1 。但是,先拿最右边的卡牌将会最大化你的可获得点数。最优策略是拿右边的三张牌,最终点数为 1 + 6 + 5 = 12 。
我的思路
用dfs递归,每次往左右两边选数的方向递归,直至选了k个数后退出递归。最后超时。
别人的思路
先求左边k个数的和 tmp。时间复杂度为O(k) 。
如果右边选了一个数,那么左边只能选k-1个数。因此此时的和为 tmp 减去左边第k个数再加上右边第一个数,记为新的 tmp。
同理,如果右边选了两个数,那么左边只能选k-2个数。因此此时的和为新的 tmp 减去左边第k-1个数再加上右边第二个数,继续以此更新 tmp。
循环k次。故总体时间复杂度为O(2k)。
别人的代码
|
|
对角线遍历ii
给你一个列表 nums ,里面每一个元素都是一个整数列表。请你依照下面各图的规则,按顺序返回 nums 中对角线上的整数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/diagonal-traverse-ii/
示例
输入:nums = [[1,2,3,4,5],[6,7],[8],[9,10,11],[12,13,14,15,16]]
输出:[1,6,2,8,7,3,9,4,12,10,5,13,11,14,15,16]
别人的思路
首先可以看到每条对角线对应的位置的横纵坐标和是递增且唯一的,如第一条对角线的横纵坐标和为0,第二条对角线的横纵坐标和为1,第三条的为2…
而具体对每一条对角线,列数越小的越在前。
因此,可以将每个元素的信息做一个元组,元组结构为(行列和值,列值,数值)。将这些元组做成一个列表并用sort()进行排序,sort()默认按元组从左到右的构成进行排序。
别人的代码
|
|
带限制的子序列和
给你一个整数数组 nums 和一个整数 k ,请你返回 非空 子序列元素和的最大值,子序列需要满足:子序列中每两个 相邻 的整数 nums[i] 和 nums[j] ,它们在原数组中的下标 i 和 j 满足 i < j 且 j - i <= k 。
数组的子序列定义为:将数组中的若干个数字删除(可以删除 0 个数字),剩下的数字按照原本的顺序排布。
提示:
- 1 <= k <= nums.length <= 10^5
- -10^4 <= nums[i] <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/constrained-subset-sum
示例
输入:nums = [10,-2,-10,-5,20], k = 2
输出:23
解释:子序列为 [10, -2, -5, 20]
别人的思路
动态规划+单调栈。
dp[i]表示以第i个值为结尾的最大子序列和,则有转移状态方程:dp[i] = max(nums[i], max(dp[j]) + nums[i]),其中 max(0, i - k) <= j <= i - 1。
用单调栈维护最大dp[j]的索引,实现查询最大dp[j]时的时间复杂度为O(1)
别人的代码
|
|
总结
LeetCode的周赛和大头菜贩卖时间冲突就很蛋疼。
做前三题被罚时太多就没继续做了,只AC第一题,排名1300/3107。