984. String Without AAA or BBB
生成字符串没有‘aaa’和’bbb’。原题
1 | Input: A = 1, B = 2 |
1 | def strWithout3a3b(self, A, B): |
455. Assign Cookies
发小饼干,s为若干个饼干的大小,g为每个人需要的大小,没人发的饼干不能比要求的size小,问最多可以满足几个人。原题
1 | Input: [1,2], [1,2,3] |
1 | def findContentChildren(self, g: List[int], s: List[int]) -> int: |
860. Lemonade Change
柠檬找零,每人买一个柠檬,(价值5)可能付5, 10, 20面值的钞票,问零钱是否能找开。原题
1 | Input: [5,5,5,10,20] |
方法一:defaultdict
。
1 | def lemonadeChange(self, bills: 'List[int]') -> 'bool': |
944. Delete Columns to Make Sorted
找出并行项中未排序的个数。原题
方法一:sorted
要比any
快,感觉是Cpython的优化导致,理论上来说应该是any快。
1 | def minDeletionSize(self, A: 'List[str]') -> 'int': |
55. Jump Game
跳跃游戏,数组中每个元素表示下一步的距离,问是否能跳到最后索引位置。原题
1 | Input: [2,3,1,1,4] |
1 | def canJump(self, nums: List[int]) -> bool: |
1005. Maximize Sum Of Array After K Negations
K次取负后的数组最大和。原题
1 | Input: A = [3,-1,0,2], K = 3 |
方法一:竞赛的时候,写得比较麻烦,分了两个数组,还考虑了0,后来看lee神的整理一下。注意最后一步要用一下min
,否则获取不了最小值。
1 | def largestSumAfterKNegations(self, A: List[int], K: int) -> int: |
1029. Two City Scheduling
两个城市调度。每个坐标表示,去A和B的花费,使花费最小。原题
1 | Input: [[10,20],[30,200],[400,50],[30,20]] |
方法一:假设左边的人留在A,右边的人留在B,如果不是最优解,那么右边的人r需要移到左边,左边的人l需要移到右边,相当于从l[0]+r[1]
变为了l[1]+r[0]
,即l[1]-l[0]+r[0]-r[1]<0
时需要交换两个城市,推导可得出,l[0]-l[1] > r[0]-r[1]
,则得出排序规则。
1 | def twoCitySchedCost(self, costs: List[List[int]]) -> int: |
1042. Flower Planting With No Adjacent
联通图染色问题,paths表示相邻的花园,相邻的花园中不能种同一种花,一种有四种花。原题
方法一:
1 | def gardenNoAdj(self, N: int, paths: List[List[int]]) -> List[int]: |
1046. Last Stone Weight
最后一块石头的质量。每次从石头堆中拿出两块最重的pk,剩下为二者之差。原题
方法一:暴力排序。
1 | def lastStoneWeight(self, stones: List[int]) -> int: |
方法二:使用堆。
1 | def lastStoneWeight(self, stones: List[int]) -> int: |
1090. Largest Values From Labels
给一个集合,每个元素有一个值values[i]
与标签labels[i]
。这里要选择一个子集,使得子集的元素个数不超过num_wanted
,而且相同标签的元素个数不超过use_limit
。求子集的最大和。原题
1 | Input: values = [5,4,3,2,1], labels = [1,1,2,2,3], num_wanted = 3, use_limit = 1 |
方法一:此题大部分时间花在理解题意,英文原文非常容易误解。
1 | def largestValsFromLabels(self, values: List[int], labels: List[int], num_wanted: int, use_limit: int) -> int: |
1094. Car Pooling
一辆车接旅客,根据旅客的人数,上下车位置,判断是否可以载完所有的旅客。原题
1 | Input: trips = [[2,1,5],[3,3,7]], capacity = 4 |
方法一:将旅客上下车地点排序。
1 | def carPooling(self, trips: List[List[int]], capacity: int) -> bool: |
1403. Minimum Subsequence in Non-Increasing Order
最小的宽度的和大于剩余数的子序列。原题
1 | Input: nums = [4,3,10,9,8] |
方法一:排序。
1 | def minSubsequence(self, nums: List[int]) -> List[int]: |
1400. Construct K Palindrome Strings
是否能用给定的字符串够成k个回文串。原题
1 | Input: s = "annabelle", k = 2 |
方法一:能否构成回文串,要看奇数个字符是否小于等于k。1
2
3
4def canConstruct(self, s: str, k: int) -> bool:
from collections import Counter
odd_c = sum(cnt&1==1 for cnt in Counter(s).values())
return odd_c <= k <= len(s)
45. Jump Game II
跳跃游戏。每个位置写了最远距离。原题
1 | Input: [2,3,1,1,4] |
方法一:使用了与1024题一样的方法。
1 | def jump(self, nums: List[int]) -> int: |
方法二:使用两个指针,表示了一个范围,每次增加一步时,在这个范围中找到下一次最右的距离,为了不让范围重叠, 让left=right+1
,直到最右点到达末尾。
1 | def jump(self, nums: List[int]) -> int: |
1296. Divide Array in Sets of K Consecutive Numbers
数组能否分成连续的k个元素的子数组。原题
1 | Input: nums = [1,2,3,3,4,4,5,6], k = 4 |
方法一:首次ac的方法。每次取最小的key比较耗时。
1 | def isPossibleDivide(self, nums: List[int], k: int) -> bool: |
1 | def isPossibleDivide(self, nums: List[int], k: int) -> bool: |
1282. Group the People Given the Group Size They Belong To
将元素分组到指定的size中。原题
1 | Input: groupSizes = [3,3,3,3,3,1,3] |
方法一:比赛时用的sort,其实有O(n)的方法。
1 | def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]: |
1 | def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]: |
1253. Reconstruct a 2-Row Binary Matrix
两个二进制数组,给出每个累加1的和,和列的和,重建这个二进制数组,答案不唯一。原题
1 | Input: upper = 2, lower = 1, colsum = [1,1,1] |
方法一:竞赛时的方法写的太java。因为在于贪心的条件选择先塞满第一个数。这样会徒增一些没用的判断。
1 | def reconstructMatrix(self, upper: int, lower: int, colsum: List[int]) -> List[List[int]]: |
1 | def reconstructMatrix(self, upper: int, lower: int, colsum: List[int]) -> List[List[int]]: |
1247. Minimum Swaps to Make Strings Equal
两个包含x和y的字符串,互换任意两个字符,最小需要多少次才能相等。原题
1 | Input: s1 = "xx", s2 = "yy" |
方法一:尽量多的匹配,’xx’和’yy’这样只需要一步。ac倒是ac了,写法上看着有点烂。
1 | def minimumSwap(self, s1: str, s2: str) -> int: |
方法二:优化一下。
1 | def minimumSwap(self, s1: str, s2: str) -> int: |
406. Queue Reconstruction by Height
根据没跟人的高度和前面比他高的k个人,重建队列。原题
1 | Input: |
方法一:看了答案,理解起来也不是很难,根据高度来排序,每次选出一个人插入到队列中,因为队列里的人都是比他高的。
1 | def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]: |
1488. Avoid Flood in The City
rains表示哪个湖会下雨,0的时候表示可以选择一个湖抽干水,如果有湖水在抽干前又下雨了,那么就会发洪水,返回-1,然后需要返回一个数组,表示每天应该抽干哪个湖的水,答案不唯一。原题
1 | Input: rains = [1,2,0,0,2,1] |
方法一:竞赛的时候没有做出来,在多次wa后TLE了,使用的方式是二分查找修改要抽哪天的水。没有想到用堆。而且整体的思路有一种滞后性,就是当遇见第二次下雨的时候再去找0的那天抽干哪个湖的水。这个方法遍历了两次数组,第一次将每个湖下雨的天数记录下来。然后可以抽水的时候用一个堆去计算最近的哪个湖会再次下雨,这样优先抽干这个湖的水。to_empty中记录索引。
1 | def avoidFlood(self, rains: List[int]) -> List[int]: |
1505. Minimum Possible Integer After at Most K Adjacent Swaps On Digits
一个数字最多交换K次相邻的字符,使其表示的数字最小,可以0开头。原题
1 | Input: num = "4321", k = 4 |
方法一:据说是字节的面试题。contest时卡在了第三题,此题没有时间看。这个方法是超时的。
1 | def minInteger(self, num: str, k: int) -> str: |
1 | class FenWick(object): |
763. Partition Labels
将字符串S尽可能分成多的部分,不同部分不能有相同的字符。原题
1 | Input: S = "ababcbacadefegdehijhklij" |
方法一:一开始想的方法。每次遇到之前的元素就用栈的方式来合并。
1 | def partitionLabels(self, S: str) -> List[int]: |
1 | def partitionLabels(self, S: str) -> List[int]: |
1 | def partitionLabels(self, S: str) -> List[int]: |
621. Task Scheduler
每两个相同任务之间需要有n个时间,不足则需要闲置,问最少的任务调度完成时间是多少。原题
1 | Input: tasks = ["A","A","A","B","B","B"], n = 2 |
方法一:使用堆。
1 | def leastInterval(self, tasks: List[str], n: int) -> int: |
M*(n+1)
的矩阵(最后一行可能不满),将最多的任务排在每一列中。Mct表示最多的任务有多少个。那么总时间为(M-1)(n+1)+Mct
。
如果还有任务没有放置,该怎么办?这时只要增加宽度,对于CPU来说,相当于没有空闲时间,一直在满负载运行。
1 | def leastInterval(self, tasks: List[str], N: int) -> int: |
1536. Minimum Swaps to Arrange a Binary Grid
二维矩阵,每次换相邻的2行,最小步数使左上右下的对象线上方全是0.原题
方法一:贪心。曾经做过一道类似的题,是每次变换十字形,然后最后变成全是0,那道题用了转换的方式,将数组转换成了一个二维数字。受到了那题的影响,比赛时想的是BFS的方法,所以最后超时了。为什么贪心的方法可行,因为每行所需的结尾0的个数是越来越少的,所以每次将所满足的行移到最上,下面的行需要的个数不会超过此行。
1 | def minSwaps(self, grid: List[List[int]]) -> int: |
435. Non-overlapping Intervals
删除最少的段,使剩余的不重复。原题
1 | Input: [[1,2],[2,3],[3,4],[1,3]] |
方法一:排序。一开始没有加key,为什么是这样的条件呢,因为需要每次选取最小的end,才能保证容纳更多的段。
1 | def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: |
134. Gas Station
说有这么一个加油站,每个加油站能加gas[i]的油量,走到下一个站需要花费cost[i]的油量,这些加油站围绕成一个圈,只有从一个站走才能顺时针走完一圈,问这个站的索引是多少,如果没有,返回-1。原题
1 | Input: |
方法一:首次ac的方法。找到油量消耗最多的点,然后让其最后经过那里。
1 | def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int: |
1 | def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int: |
1558. Minimum Numbers of Function Calls to Make Target Array
最小步骤能将全是0的数组变为目标数组。每步可以选择一个元素+1,或者所有元素*2。原题
1 | Input: nums = [1,5] |
方法一:比赛时想到了这个方法,从后往前算,然后尽量/2,但是感觉会超时,所以没有提交。
1 | def minOperations(self, nums: List[int]) -> int: |
1 | def minOperations(self, A: List[int]) -> int: |
1568. Minimum Number of Days to Disconnect Island
把刚好存在一个岛屿变成2个或没有,最少需要几步。每步可以沉没一个格子。原题
1 | Input: grid = [[0,1,1,0],[0,1,1,0],[0,0,0,0]] |
方法一:这题需要想明白一件事,对于任意的岛屿,我找一个角沉没它旁边两个,就能将其变成一个单独的岛屿。那么也就是说 最多需要2步就行。
1 | def minDays(self, grid: List[List[int]]) -> int: |
方法二:不用深拷贝,用集合判断点是否重复。
1 | def minDays(self, grid: List[List[int]]) -> int: |
1567. Maximum Length of Subarray With Positive Product
最长的子数组累乘为正数。原题
1 | Input: nums = [1,-2,-3,4] |
方法一:比赛时的方法。这题作为竞赛第二题有点稍难,但还是完成了。
1 | def getMaxLen(self, nums: List[int]) -> int: |
方法二:0这个元素不是很好判断,所以先将数组以0分割。
1 | def getMaxLen(self, nums: List[int]) -> int: |
1 | def getMaxLen(self, nums: List[int]) -> int: |
881. Boats to Save People
最少需要多少小船救人。小船限重为limit,最多能装俩人。根据人的重量,最少需要多少小船。原题
1 | Input: people = [3,2,2,1], limit = 3 |
方法一:抱着超时的心态提交,居然ac了。但是太慢了。
1 | def numRescueBoats(self, people: List[int], limit: int) -> int: |
1 | def numRescueBoats(self, people: List[int], limit: int) -> int: |
方法三:用指针。
1 | def numRescueBoats(self, p: List[int], limit: int) -> int: |
1 | def numRescueBoats(self, p: List[int], limit: int) -> int: |
1405. Longest Happy String
最长的欢乐字符串,有’abc’3个字符组成,并且不存在’aaa’这种三连的情况。给定每个字符的个数,问最长可以生成多长的这样的字符串。原题
1 | Input: a = 1, b = 1, c = 7 |
方法一:用最大堆实现,注意这里选择第二多元素时要添加一个字符,因为有时候第二个字符可能不够分割。
1 | def longestDiverseString(self, a: int, b: int, c: int) -> str: |
870. Advantage Shuffle
将A重新排序,使得对应位置>B的数尽可能地多。原题
1 | Input: A = [2,7,11,15], B = [1,10,4,11] |
方法一:很直观的贪心算法。将AB排序。每次拿出最大的和B最大的比,如果比不过,就拿最小的顶上。类似于田忌赛马。
1 | def advantageCount(self, A: List[int], B: List[int]) -> List[int]: |
方法二:这个方法很新颖,把能赢的位置放到take中。然后A会剩下一部分,这部分顺序已经无所谓了,所以当take不到时,就从A随便返回一个就行了
1 | def advantageCount(self, A: List[int], B: List[int]) -> List[int]: |
861. Score After Flipping Matrix
一个二维矩阵,可以按行,列翻转,问最大每行和是多少。原题
1 | Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]] |
方法一:贪心,首先保证行首位是1,然后列翻转时保证多余一半1.
1 | def matrixScore(self, A: 'List[List[int]]') -> 'int': |
1 | def matrixScore(self, A: List[List[int]]) -> int: |
452. Minimum Number of Arrows to Burst Balloons
有很多个气球绑在了水平线上,给了这些气球的start, end表示和水平线相交的点。问最少需要多少个飞镖才能将所有气球扎坏。
1 | Input: |
方法一:贪心法,尽量扎多点。
1 | def findMinArrowShots(self, points: List[List[int]]) -> int: |
1 | def findMinArrowShots(self, points: List[List[int]]) -> int: |
1589. Maximum Sum Obtained of Any Permutation
说要查询某一段,进行n次查询,问将数组如何排列能使线段的总和最大。
方法一:这题竞赛时没做出来,心态崩了。不知道怎么构造一个对线段的计数,用Counter超时了。剩下的一小时就是拼命地构造一个不重复的线段tuple,最后也没完成。正确的思路是这样的,在线段的起点+1,结束点后一位-1,这样在累加的时候就会把这段1都算出来。
1 | def maxSumRangeQuery(self, nums: List[int], requests: List[List[int]]) -> int: |
1599. Maximum Profit of Operating a Centennial Wheel
这题看起来很复杂,作为竞赛第二题还算可以。有这样一个摩天轮,一次只能上4个人,转一次要花费runningCost,门票boardingCost。给定一个游客时间人数队列,问最大利润时在第几轮(摩天轮转了多少圈)。
方法一:竞赛时的答案擦边过的。
1 | def minOperationsMaxProfit(self, cust: List[int], bc: int, rc: int) -> int: |
方法二:实际上最后需要一个取余操作就行,不用再模拟了。
1 | def minOperationsMaxProfit(self, cust: List[int], bc: int, rc: int) -> int: |
1605. Find Valid Matrix Given Row and Column Sums
给定一个二维数组行的和与列的和,求这个二维数组,答案不唯一。
方法一:这道题比赛用回溯法写的,超时了一次,然后改为倒序勉强过了。其实可以用贪心,每次都尽量将最大的数填进去,但是并不知道怎么证明。Lee也没有给出很好的证明方式。
1 | def restoreMatrix(self, rowSum: List[int], colSum: List[int]) -> List[List[int]]: |
1616. Split Two Strings to Make Palindrome
从某个索引出切断两个字符串,相互拼接是否能组成回文串。
1 | Input: a = "ulacfd", b = "jizalu" |
方法一:竞赛时最后一分钟做了出来,顶着压力AC了。不过之前超时了两次,妄想用暴力法过,没有得逞。整理一下代码。以每个字符串中心找最大的回文串,然后比较相互的头尾相交。
1 | def checkPalindromeFormation(self, a: str, b: str) -> bool: |
方法二:Lee的方法。从头尾找相同,判断中间是否回文。
1 | def checkPalindromeFormation(self, a: str, b: str) -> bool: |
1 | def checkPalindromeFormation(self, a: str, b: str) -> bool: |
948. Bag of Tokens
你的初始能量为 P,初始分数为 0,只有一包令牌。令牌的值为 token[i],每个令牌最多只能使用一次,可能的两种使用方法如下:如果你至少有 token[i] 点能量,可以将令牌置为正面朝上,失去 token[i] 点能量,并得到 1 分。如果我们至少有 1 分,可以将令牌置为反面朝上,获得 token[i] 点能量,并失去 1 分。在使用任意数量的令牌后,返回我们可以得到的最大分数。
1 | Input: tokens = [100,200,300,400], P = 200 |
方法一:双指针。很容易想到是贪心,因为分数都是一样的,以最少的能量换最多的分。10分钟AC。
1 | def bagOfTokensScore(self, tokens: List[int], P: int) -> int: |
方法二:Lee的写法,deque,将判断放到while 中了。
1 | def bagOfTokensScore(self, tokens: List[int], P: int) -> int: |
135. Candy
N个学生站成一排,每个人有个比率,要求每人至少发一块糖,比率如果比挨着的两位同学大,那么糖要比他们多。问最少需要多少个糖。
方法一:左右遍历两次。从左向右遍历之后,保证每人比左侧大的条件,再从右向左遍历,保证每人比左侧大的条件。注意13452
的情况,反向遍历时要去最大值。因为左侧遍历完事12341
。
1 | def candy(self, ratings: List[int]) -> int: |
646. Maximum Length of Pair Chain
能组成的最长的链。和300题一样。
1 | Input: [[1,2], [2,3], [3,4]] |
方法一:dp, O(n^2)的暴力方法。
1 | def findLongestChain(self, pairs: List[List[int]]) -> int: |
1 | def findLongestChain(self, pairs: List[List[int]]) -> int: |
1647. Minimum Deletions to Make Character Frequencies Unique
最少需要删除多少次字母使得每个字母的频率都不一样。
1 | Input: s = "aaabbbcc" |
方法一:比赛时写得比较直观的方法。
1 | def minDeletions(self, s: str) -> int: |
1 | def minDeletions(self, s: str) -> int: |
1648. Sell Diminishing-Valued Colored Balls
有这么几种颜色的球,每种球有一些个数。当取出一个球的时候,分数为剩下同种颜色的球,问一共需要取orders个球,问最大的分是多少?
1 | Input: inventory = [2,5], orders = 4 |
方法一:很容易看出是一道贪心的题,比赛时超时了一次,因为想用堆来模拟。后来想到了用数学的方式。就是尽量将所有的剩下球平均,因为越少拿球分就越少。这里用了一个动态的求平均的方式。不是最优解,700+ms,beats 30%,还有很大的优化空间。
1 | def maxProfit(self, inventory: List[int], orders: int) -> int: |
1653. Minimum Deletions to Make String Balanced
最少的步数可以让字符串中没有b在a前的情况。
1 | Input: s = "aababbab" |
方法一:比赛时想着和秋叶收藏集
一题很像,就用了dp,也能过,不过不是最优。
1 | def minimumDeletions(self, s: str) -> int: |
1 | def minimumDeletions(self, s: str) -> int: |
1663. Smallest String With A Given Numeric Value
每个字母对应一个值,给定一个长度为n的条件,求这个条件字符总和为k的最小字典序的字符串。
1 | Input: n = 3, k = 27 |
方法一:这题我想错了一个点,z对应的是26而不是25。导致用了1个小时才提交上。周赛第一题用了44秒的好成绩都浪费掉了。
1 | def getSmallestString(self, n: int, k: int) -> str: |
aaxzzz
。所以用数学的思路可以直接求出。
1 | def getSmallestString(self, n: int, k: int) -> str: |
1664. Ways to Make a Fair Array
删除一个数使得数组奇数位偶数位和相等,一共有多少种删除的方法。
1 | Input: nums = [2,1,6,4] |
方法一:前缀和,竞赛时想到了,但是没做出来,因为看错了题,忽略了删除一次这个条件。这里是Lee的写法,维持一个当前的奇偶和与右侧的奇偶和,当删除某个数后,后面的奇偶位互换。
1 | def waysToMakeFair(self, nums: List[int]) -> int: |
767. Reorganize String
重排字符串使其没有相邻的两个字符使相同的。
1 | Input: S = "aab" |
方法一:使用堆实现的。每次从堆中取一个或两个。
1 | def reorganizeString(self, S: str) -> str: |
方法二:by @Stefan。为何内层也要sorted一下,是因为[a, b, b, a]
会保留原来的相对顺序。
1 | def reorganizeString(self, S: str) -> str: |
659. Split Array into Consecutive Subsequences
将一个升序的数组,拆分重连续的子数组段,长度不能小于3.
1 | Input: [1,2,3,3,4,4,5,5] |
方法一:By@lee215。挺难想的方法,left表示每个数剩了多少个。end表示以这个数结尾的有几个。当我没法将当前的数追加到前一段的结尾时,也没法找到后两个连续的数时,就不能拆分成功。
1 | def isPossible(self, A: List[int]) -> bool: |
1702. Maximum Binary String After Change
对于一个二进制的字符串,你可以将00
变成10
, 也可以将10
变成01
,问可以变成的表示最大的十进制的数对应的字符串是多少。
1 | Input: binary = "000110" |
方法一:竞赛时想出来了,无非是找到规律就行,代码写的过于冗长。思路是开头的1不用管,将后面所有的0冒泡到最高位,0000
可以变成1110
,最后以一些1结尾。这里是Lee的优雅写法
1 | def maximumBinaryString(self, binary: str) -> str: |
1727. Largest Submatrix With Rearrangements
重新排列二维矩阵,可以得到的最大的都是1的矩阵面积是多少。
1 | Input: matrix = [[0,0,1],[1,1,1],[1,0,1]] |
方法一:比赛时没有做出来,想到了贪心和排序,但是没想到列的怎么保持一致的顺序。此题和84,85很像,印象不深,所以没有关联上。从列上从上至下做一个累加,所以累加的数都到了一行,这样再排序每行都是独立的。
1 | def largestSubmatrix(self, matrix: List[List[int]]) -> int: |
1737. Change Minimum Characters to Satisfy One of Three Conditions
给定两个字符串a和b,都是由小写字母组成。然后每次允许将任意字符串的一个字符改成任意一个字符最后满足下列三种条件之一:问最小操作步数是多少。1. a的所有字符严格小于b;2:b的所有字符严格小于a;3:a,b都是一种相同的字符。
1 | Input: a = "aba", b = "caa" |
方法一:竞赛时没有做出来,就差一点。第三种条件很容易想到。前两种不好想,需要用到前缀和+错位。这点我想到了,没想到是以分割字符来暴力枚举。将a,b字符串转成字母计数的数组,以a~y中的字母d来分割,a串全部小于等于d,b串全部大于d。
1 | def minCharacters(self, a: str, b: str) -> int: |
方法二:可以用总和减去前缀和来求得后缀和。Lee的方法。
1 | def minCharacters(self, a: str, b: str) -> int: |
1665. Minimum Initial Energy to Finish Tasks
最少需要多少能量完成所有的任务。每个任务有一个最低能量和消耗的能量。
1 | Input: tasks = [[1,2],[2,4],[4,8]] |
方法一:很容易想到贪心,要排序,但是根据什么排序很重要。因为 minimum 表示的是”开始做这个任务的时候,拥有的最小能量值是多少“;actual 则是”做这个任务所消耗的能量值“。所以,minimum - actual 的结果,就是”完成这个任务以后,剩余的能量值的最小值“。为了完成所有的任务,我们显然希望剩余的能量值越多越好。所以,我们应该先完成“使得剩余的能量值多的任务”,即 minimum - actual 大的任务;这样有更多的能量,去完成别的任务。
1 | def minimumEffort(self, tasks: List[List[int]]) -> int: |
1754. Largest Merge Of Two Strings
合并两个字符串,字典序最大。每次从两个单词开头拿字符。
1 | Input: word1 = "cabaa", word2 = "bcaaa" |
方法一:模拟。
1 | def largestMerge(self, word1: str, word2: str) -> str: |
方法二:递归。
1 | def largestMerge(self, s1: str, s2: str) -> str: |
1591. Strange Printer II
二维矩阵中,每次能打一个递增的数字,但是必须打出矩形,后打的字可以覆盖之前的,问一个结果是否能被打印出来。
1 | Input: targetGrid = [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]] |
方法一:此题需要逆向思维,将数字还原为0。需要注意一点,不能排序从大到小因为,可能有[4,3,3,4]
的情况。所以判断条件是,当所有的颜色都不能透过矩形变小时,返回False。遍历过程中可以置为0,因为当大数可打印时,其可以替换为任何比它小的数字,相当于万能,所以在检测到矩形时,就将其置为0.
1 | def isPrintable(self, g: List[List[int]]) -> bool: |
1793. Maximum Score of a Good Subarray
从数组k的位置向两侧延伸,子数组分数(最小值*长度)最大为多少
1 | Input: nums = [1,4,3,7,4,5], k = 3 |
方法一:这周周赛简单,作为第四题过于简单。我这里想了最后才用了二分法做出来。
1 | def maximumScore(self, nums: List[int], k: int) -> int: |
方法二:贪心,双指针。就尽量让最小值减少得慢。
1 | def maximumScore(self, nums: List[int], k: int) -> int: |
1806. Minimum Number of Operations to Reinitialize a Permutation
操作多少次,数组能变回原样
- If
i % 2 == 0
, thenarr[i] = perm[i / 2]
. - If
i % 2 == 1
, thenarr[i] = perm[n / 2 + (i - 1) / 2]
.
1 | Input: n = 4 |
方法一:比较简单,写法上有点 丑陋。
1 | def reinitializePermutation(self, n: int) -> int: |
1 | def reinitializePermutation(self, n: int) -> int: |