LeetCode – Smallest Rotation with Highest Score
Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1], A{K+2], ... A[A.length - 1], A[0], A[1], ..., A[K-1]. Afterward, any entries that are less than or equal to their index are worth 1 point.
For example, if we have [2, 4, 1, 3, 0], and we rotate by K = 2, it becomes [1, 3, 0, 2, 4]. This is worth 3 points because 1 > 0 [no points], 3 > 1 [no points], 0 <= 2 [one point], 2 <= 3 [one point], 4 <= 4 [one point].
Over all possible rotations, return the rotation index K that corresponds to the highest score we could receive. If there are multiple answers, return the smallest such index K.
Example 1:
Input: [2, 3, 1, 4, 0]
Output: 3
Explanation:
Scores for each K are listed below:
K = 0, A = [2,3,1,4,0], score 2
K = 1, A = [3,1,4,0,2], score 3
K = 2, A = [1,4,0,2,3], score 3
K = 3, A = [4,0,2,3,1], score 4
K = 4, A = [0,2,3,1,4], score 3
So we should choose K = 3, which has the highest score.
Example 2:
Input: [1, 3, 0, 2, 4]
Output: 0
Explanation: A will always have 3 points no matter how it shifts.
So we will choose the smallest K, which is 0.
Note:
A will have length at most 20000.
A[i] will be in the range [0, A.length].
暴力解法会超时
class Solution {
public int bestRotation(int[] A) {
if(A == null || A.length == 0){
return 0;
}
int k = 0;
int max = 0;
int[] points = new int[A.length];
for(int i = 0; i < A.length; i++){
for(int j = 0; j < A.length; j++){
int newIndex = (A.length - (j-i)) % A.length;
if(newIndex >= A[i]){
points[j]++;
}
}
}
for(int i = 0; i < points.length; i++){
if(points[i] > max){
max = points[i];
k =i;
}
}
return k;
}
}
这道题给了我们一个长度为N的数组,说是数组中的数字的范围都在[0, N]之间,然后定义了一个旋转操作,比如在位置K进行旋转,数组在K位置断开,新数组以A[k]为开头数字,断开的前半段数组直接拼到末尾即可。然后又定义了一种积分规则,说是如果某个坐标位置大于等于其数字的话,得1分,让我们求出某个旋转位置K,使得其积分最大,如果积分相同的话,取位置小的K。通过分析题目中的例子,发现题目并不难理解。博主首先尝试了暴力搜索的方法,就是遍历每个K值,生成旋转后的数组,然后再统计得分,不幸挂掉了。那么我们必须要想出更好的解法才行。首先我们想,如果数组中的每个数字都跟其坐标值相同的话,比如[0, 1, 2, 3, 4],那么肯定得分最高,即K=0。但实际上并不会是有序的,而且并不是每个数字都会出现,题目中只给了数字的范围,有可能会有重复数字哦。说实话这道题博主研究大神lee215的帖子,都研究了好久,最后终于有些明白了,就大概讲讲吧,如果有不对的地方欢迎大家指正。
这道题博主感觉还是很有难度的,而且答案的思路也十分巧妙,并没有采用brute force那种直接求每一个K值的得分,而是反其道而行之,对于每个数字,探究其跟K值之间的联系。首先我们要讨论一下边界情况,那么就是当A[i] = 0 或 N 的情况,首先如果A[i] = 0的话,那么0这个数字在任何位置都会小于等于坐标值,所以在任何位置都会得分的,那么其实可以忽略之,因为其不会对最大值产生任何影响,同理,如果A[i] = N的时候,由于长度为N的数组的坐标值范围是[0, N-1],所以数字N在任何位置都不得分,同样也不会对最大值产生任何影响,可以忽略之。那么我们关心的数字的范围其实是[1, N-1]。在这个范围内的数字在旋转数组的过程中,从位置0变到N-1位置的时候,一定会得分,因为此范围的数字最大就是N-1。这个一定得的分我们在最后统一加上,基于上面的发现,我们再来分析下题目中的例子 [2, 3, 1, 4, 0],其中红色数字表示不得分的位置:
A: 1 0 (K = 0)
A: 1 0 2 (K = 1)
A: 0 2 3 (K = 2)
A: 0 2 3 1 (K = 3)
A: 0 1 4 (K = 4)
idx: 0 1 2 3 4
对于某个数字A[i],我们想知道其什么时候能旋转到坐标位置为A[i]的地方,这样就可以得分了。比如上面博主标记了红色的数字3,最开始时的位置为1,此时是不得分的,我们想知道其什么时候能到位置3,答案是当K=3的时候,其刚好旋转到位置3,K再增加的时候,其又开始不得分了。所以这个最后能得分的临界位置是通过 (i - A[i] + N) % N 得到,那么此时如果K再增加1的话,A[i]就开始不得分了(如果我们suppose每个位置都可以得分,那么不得分的地方就可以当作是失分了),所以我们可以在这个刚好开始不得分的地方标记一下,通过-1进行标记,这个位置就是 (i - A[i] + 1 + N) % N。我们用一个长度为N的change数组,对于每个数字,我们都找到其刚好不得分的地方,进行-1操作,那么此时change[i]就表示数组中的数字在i位置会不得分的个数,如果我们仔细观察上面红色的数字,可以发现,由于是左移,坐标在不断减小,所以原先失分的地方,在K+1的时候还是失分,除非你从开头位置跑到末尾去了,那会得分,所以我们要累加change数组,并且K每增加1的时候,要加上额外的1,最后change数组中最大数字的位置就是要求的K值了,参见代码如下:
public int bestRotation(int[] A) {
int N = A.length;
int change[] = new int[N];
for (int i = 0; i < N; ++i) change[(i - A[i] + 1 + N) % N] -= 1;
int max_i = 0;
for (int i = 1; i < N; ++i) {
change[i] += change[i - 1] + 1;
max_i = change[i] > change[max_i] ? i : max_i;
}
return max_i;
}
LeetCode – Smallest Rotation with Highest Score的更多相关文章
- [LeetCode] Smallest Rotation with Highest Score 得到最高分的最小旋转
Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1 ...
- 75th LeetCode Weekly Contest Smallest Rotation with Highest Score
Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1 ...
- 【leetcode】Smallest Rotation with Highest Score
题目如下: Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], ...
- [Swift]LeetCode798. 得分最高的最小轮调 | Smallest Rotation with Highest Score
Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1 ...
- [LeetCode] Smallest Rectangle Enclosing Black Pixels 包含黑像素的最小矩阵
An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black ...
- LeetCode Smallest Rectangle Enclosing Black Pixels
原题链接在这里:https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/ 题目: An image is rep ...
- [LeetCode] Smallest Range 最小的范围
You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...
- [LeetCode] Smallest Good Base 最小的好基数
For an integer n, we call k>=2 a good base of n, if all digits of n base k are 1. Now given a str ...
- LeetCode 856. 括号的分数(Score of Parentheses)
856. 括号的分数 856. Score of Parentheses 题目描述 给定一个平衡括号字符串 S,按下述规则计算该字符串的分数: () 得 1 分. AB 得 A + B 分,其中 A ...
随机推荐
- U帮忙U盘装系统工具使用教程
在用U盘装系统时首先我们需要了解一下U帮忙U盘启动盘的制作以及BIOS设置U盘启动和U盘装系统步骤后才能让操作更顺利的完成,下面就来说说U帮忙U盘装系统工具使用教程,希望对大家有所帮助! 如果您不了解 ...
- bzoj2330
题解: 差分约束系统 要我们求最小值 显然就是转化为最长路 然后spfa一下即可 代码: #include<bits/stdc++.h> using namespace std; ; lo ...
- nginx:支持https
1.查看nginx模块 nginx -V 注意是大写的V,小写的v是查看版本号的命令. 如果看到with-ssl那就是有的 2.注册ssl证书并下载 免费的ssl证书有: Let's Encrypt ...
- 国内npm镜像使用
淘宝npm镜像 搜索地址:http://npm.taobao.org/ registry地址:http://registry.npm.taobao.org/ cnpmjs镜像 搜索地址:http:// ...
- 5.3 C++用顶层函数重载操作符
参考:http://www.weixueyuan.net/view/6381.html 总结: 可以将操作符重载函数声明为顶层函数. 如果以顶层函数的形式重载操作符时,二元操作符重载函数必须有两个参数 ...
- SQL-16 统计出当前各个title类型对应的员工当前薪水对应的平均工资。结果给出title以及平均工资avg。
题目描述 统计出当前各个title类型对应的员工当前薪水对应的平均工资.结果给出title以及平均工资avg.CREATE TABLE `salaries` (`emp_no` int(11) NOT ...
- The issue about the GMT paper can't display all the seismograms
I try to display seismograms using 'pssac' by the command: gmt pssac *.z -JX20c/40c -R0/// -Bx20+l'T ...
- django面试三
1.Django. Flask.Tornado框架的比较? Django: 对于django,大而全的框架它的内部组件比较多,内部提供:ORM.Admin.中间件.Form.ModelForm.Ses ...
- C++ SUBLIME TEXT3 环境配置
一.第一种方法 1.New Build System,设置C++.sublime-build编译文件 { "path": "E:\\MinGW\\bin", & ...
- Python 第一类对象
def fn(): print("我叫fn") fn() print(fn) # <function fn at 0x0000000001D12E18> fn() gn ...