这次的比赛其实因为加班的关系没有参加,然后也不想做模拟比赛了,就随便自己做了做,结果发现,还好我没有参加这次比赛,各种马失前蹄,错的各种离谱,如果参加的话估计又是要直接跌到3000名的样子了……
唉,代码之道还是任重而道远啊……
给出题目一的试题链接如下:
这一题的解题思路挺直白的,因为原数组会是一个单调非减的数组,因此,只要确保以下两点即可作为充要条件:
对此进行判断即可。
给出python代码实现如下:
class Solution:
def check(self, nums: List[int]) -> bool:
n = len(nums)
for i in range(n-1):
if nums[i] > nums[i+1]:
return nums[-1] <= nums[0] and all(nums[j] <= nums[j+1] for j in range(i+1, n-1))
return True
提交代码评测得到:耗时32ms,占用内存14.3MB。
给出题目二的试题链接如下:
这一题我一开始想岔了,用动态规划进行了解决,虽然提交也是过了,但是执行效率实在是惨不忍睹。
其实仔细分析一下这道题,这题其实挺直接的。
首先,我们将a,b,c按照从小到大顺序排列,假设a+b<=c
,那么显然答案就是a+b
。
如果a+b>c
,那么,我们只需要先对a,b进行一些内部消耗,使之满足a' + b' <= c
,即可重新套用上述的公式。
给出python代码实现如下:
class Solution:
def maximumScore(self, a: int, b: int, c: int) -> int:
a, b, c = sorted([a,b,c])
if a+b <= c:
return a+b
else:
return (a+b-c) // 2 + c
提交代码评测得到:耗时24ms,占用内存14.4MB。
给出题目三的试题链接如下:
这一题也是典型的题目简单但是想岔了类型。。。
说白了这道题只要根据题意进行逐次操作即可,但是需要注意的是,如果两个字符串的首字符相同时,会遇到一定的问题,所以我当时想着就是用动态规划,然后就各种超时……
事实上,我们没有必要只比首字符,直接对两个字符串进行比较就行了,因为当首字符相同时,我们总是希望尽可能更早的将较大的元素放到前方,这个和字符串的比较是一致的,因此这道题就瞬秒了……
给出python代码实现如下:
class Solution:
def largestMerge(self, word1: str, word2: str) -> str:
i, j, n, m = 0, 0, len(word1), len(word2)
res = ""
while i < n and j < m:
if word1[i:] < word2[j:]:
res += word2[j]
j += 1
else:
res += word1[i]
i += 1
res += word1[i:]
res += word2[j:]
return res
提交代码评测得到:耗时84ms,占用内存14.6ms。
我们给出题目四的试题链接如下:
这一题坦率地说没啥好的思路,直接的一个想法就是动态规划,但是如果暴力求解的话显然会遇到超时问题,因此,我们需要考虑一定的剪枝。
我们考虑如下几种情况:
而对于其他的情况,我们只需要考虑如下情况即可:
综上,我们即可以给出最终的代码实现。
给出python代码实现如下:
class Solution:
def minAbsDifference(self, nums: List[int], goal: int) -> int:
res = goal
nums = sorted(nums)
n = len(nums)
s = sum(nums)
@lru_cache(None)
def dp(i, j, s):
if s == goal:
return 0
elif i > j:
return abs(goal-s)
elif s > goal:
if nums[j] <= 0:
return abs(goal - s)
return min(dp(i, j-1, s-nums[j]), dp(i, j-1, s))
else:
if nums[i] >= 0:
return abs(goal - s)
return min(dp(i+1, j, s-nums[i]), dp(i+1, j, s))
return dp(0, n-1, s)
提交代码评测得到:耗时3068ms,占用内存679.2MB。
当前最优的代码实现耗时仅36ms,有近两个量级的性能提升。
因此,下面我们来看一下他们的算法思路。
看了一下当前最优的算法实现,发现他们somehow将算法复杂度直接退化到了 O ( N ) O(N) O(N)的程度。
但是坦率说,他们算法的内核没有完全看懂,所以这里就仅仅摘录在下方供读者参考,如果有看明白的请务必在评论区指导一二,万分感谢。
class Solution:
def minAbsDifference(self, nums: List[int], goal: int) -> int:
res = inf
n = len(nums)
nums.sort(key = lambda x:-abs(x))
leftmax = [0] * n
leftmin = [0] * n
pos = neg = 0
for i in range(n-1, -1, -1):
if nums[i] > 0:
pos += nums[i]
else:
neg += nums[i]
leftmax[i] = pos
leftmin[i] = neg
def backtracking(cur, index):
nonlocal res
nonlocal goal
if res == 0:
return
ncur = cur + nums[index]
if abs(ncur - goal) < res:
res = abs(ncur - goal)
if abs(cur - goal) < res:
res = abs(cur - goal)
if index == len(nums) - 1:
return
x,y = leftmin[index + 1], leftmax[index+1]
if ncur + x < goal < ncur + y:
backtracking(ncur, index + 1)
else:
res = min(res, abs(ncur + x - goal), abs(ncur + y - goal))
if cur + x < goal < cur + y:
backtracking(cur, index + 1)
else:
res = min(res, abs(cur + x - goal), abs(cur + y - goal))
backtracking(0, 0)
return res