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的更多相关文章

  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], A[K+1 ...

  2. 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 ...

  3. 【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], ...

  4. [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 ...

  5. [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 ...

  6. LeetCode Smallest Rectangle Enclosing Black Pixels

    原题链接在这里:https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/ 题目: An image is rep ...

  7. [LeetCode] Smallest Range 最小的范围

    You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...

  8. [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 ...

  9. LeetCode 856. 括号的分数(Score of Parentheses)

    856. 括号的分数 856. Score of Parentheses 题目描述 给定一个平衡括号字符串 S,按下述规则计算该字符串的分数: () 得 1 分. AB 得 A + B 分,其中 A ...

随机推荐

  1. java⑦

    1. 逻辑运算符 * 01. && 短路与 并且的关系 * 表达式1 && 表达式2 * 001.如果 表达式1为false,则不执行 表达式2 * 002.表达式1, ...

  2. flask项目结构(三)使用蓝图

    简介: Flask中的蓝图旨在针对这些情况: 把一个应用分解成一系列的蓝图.对于大型的应用是理想化的:一个项目能实例化一个应用, 初始化一些扩展,以及注册一系列的蓝图. 以一个 URL 前缀和/或子域 ...

  3. Excel 数据读入到DataSet

    using System; using System.Collections.Generic; using System.Linq; using System.Data; using System.I ...

  4. 关于macroblaze的一些理解(更新中)

    (1)添加*.elf文件: 在Design Sources工作目录中右键选择添加源文件,找到SDK目录中对应的文件夹下的Debug内*.elf文件,将其添加.然后,源文件目录更新,多出一个ELF文件夹 ...

  5. Centos7安装ansible

    CentOS下部署Ansible自动化工具 1.确保机器上安装的是 Python 2.6 或者 Python 2.7 版本: python -V 2.查看yum仓库中是否存在ansible的rpm包 ...

  6. socket 编程通信实例

    socket 编程通信实例:TCPserver: , ServerThread,  ;    WSADATA wsaData;    ,),  ;    }    ;    }    } ;    g ...

  7. hdu3001(状压dp,三进制)

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. pytest的fixture和conftest

    解决问题:用例1需要先登录,用例2不需要登录,用例3需要先登录.很显然这就无法用setup和teardown来实现了,这个时候就可以自定义测试用例的预置条件,比setup灵活很多. 1.fixture ...

  9. 1-log4j2入门

    一.入门介绍 log4j apache实现的一个开源的日志组件 slf4j 日志接口即为所有日志框架制定的一种规范的标准接口,并不是一个框架的具体实现,需要配合具体的日志框架使用(如log4j2.lo ...

  10. python day08作业答案

    1. a f=open('11.txt','r',encoding='utf-8') a=f.read() print(a) f.flush() f.close() b. f=open('11.txt ...