798. 得分最高的最小轮调
题目描述
给你一个数组 nums,我们可以将它按一个非负整数 k 进行轮调,这样可以使数组变为 [nums[k], nums[k + 1], ... nums[nums.length - 1], nums[0], nums[1], ..., nums[k-1]] 的形式。此后,任何值小于或等于其索引的项都可以记作一分。
- 例如,数组为
nums = [2,4,1,3,0],我们按k = 2进行轮调后,它将变成[1,3,0,2,4]。这将记为3分,因为1 > 0[不计分]、3 > 1[不计分]、0 <= 2[计 1 分]、2 <= 3[计 1 分],4 <= 4[计 1 分]。
在所有可能的轮调中,返回我们所能得到的最高分数对应的轮调下标 k 。如果有多个答案,返回满足条件的最小的下标 k 。
示例 1:
输入:nums = [2,3,1,4,0] 输出:3 解释: 下面列出了每个 k 的得分: k = 0, nums = [2,3,1,4,0], score 2 k = 1, nums = [3,1,4,0,2], score 3 k = 2, nums = [1,4,0,2,3], score 3 k = 3, nums = [4,0,2,3,1], score 4 k = 4, nums = [0,2,3,1,4], score 3 所以我们应当选择 k = 3,得分最高。
示例 2:
输入:nums = [1,3,0,2,4] 输出:0 解释: nums 无论怎么变化总是有 3 分。 所以我们将选择最小的 k,即 0。
提示:
1 <= nums.length <= 1050 <= nums[i] < nums.length
解法
方法一:差分数组
思考
轮转 \(k\) 后,\(nums[i]\) 移到 \((i-k)\bmod n\),当新下标 \(\ge nums[i]\) 时得一分。\(n\le 10^5\),对每个 \(k\) 计分过慢。
每个 \(nums[i]\) 对一段连续的 \(k\) 得分,这段是环上的区间。差分数组在左端 \(+1\)、右端 \(-1\),前缀和即各 \(k\) 的得分。
取得分最大且 \(k\) 最小者。
对于每个数,都有一个固定的 k 生效区间。我们先利用差分,预处理每个数的 k 生效区间。有最多个数能覆盖到的 k 即是答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |