前言
是本篇博客主要记录和复习,在LeetCode上刷到的这道题,很有意思!
提示:以下是本篇文章正文内容,下面案例可供参考
一、问题描述
很不错的一道题,花费了一天时间来思考,题意不容易读懂,可以直接看示例1的举例,这道题的本质就是寻找得分Score相同的数组个数,所以差分数组的功能就变得特别显著,要解决这道题我参考了不少大佬的题解,这其中会有一些我自己的思考和借鉴的地方,其中借鉴的地方我会注明链接,需要的朋友可以自己前去查阅。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/smallest-rotation-with-highest-score/
二、解题思路及代码
1.换角度解读题意
以下的思考过程参考了 Benhao大佬的题解,其中设定
- 差分数组为diff,其长度为len(nums)+1,注意:diff[i] += 1 表示所属位置i可以得分,diff[i] -= 1 表示所属位置 i 处不能得分。
- i 为 nums 数组中移动的下标,是 [0,len(nums)-1]范围内的整数,
- num为 nums 数组中的元素,
- 由于数组的下标向左论调,因而记论调的或向左移动的步数为 k。
- 具体步骤如下
- 当遇到 i >= num 时 使用 diff[0] 记录 初始数组中所含的满足要求的组合:
- 此时 i 所处的区间表示为: [0, … ,num-1] [num, … ,i, …, n-1]
- 当i位于 [num,n-1] 时,k 在 [num,n-1] 中向 num 方向移动,则记录此时的 diff[i+1] += 1
- 当 k 移动至 [0,num-1]区间时,则记录 diff[i -(num-1)] -= 1
- 当遇到 i < num 时,此时 i 所处的区间表示为:[0, … , i , … , num-1] [num, … ,n-1]
- 当i位于 [0,num-1] 时,k在 [num,n-1] 中向左移动,则记录diff[i+1] += 1
- 当 k 移动至 [0,num-1] ,由于绕了一圈(从数组后方进入),则记录 diff[i+n-(num-1)] -= 1
单看文字说明可能有些懵!可以参考ricolove朋友的这篇题解的图书(如下所示)去理解上面的步骤。
注意这里的表格少了最后一列,不过并不妨碍理解。
2.具体代码及部分结果展示
class Solution:
def bestRotation(self, nums: List[int]) -> int:
n = len(nums)
diff = [0] * (n+1)
for i,num in enumerate(nums):
if i >= num:
diff[0] += 1
diff[i+1] += 1
diff[i-(num-1)] -= 1
else:
diff[i+1] += 1
diff[i+n-(num-1)] -= 1
ans,cur,max = 0,0,-inf
for i in range(n+1):
cur += diff[i]
if cur > max:
ans,max = i,cur
return ans
三个结果的展示:
三、总结
这道题挺有趣的,差分数组对我来说是一个比较陌生的词汇,不够这种表示两个数组关系的数组,在许多为节省运算时间的编程上效果显著,是非常值得学习的一块内容!