题目如下:

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

结题思路:本题主要考察的是算法的时间复杂度,如果时间复杂度是O(n^2)的话,系统会判定超时,所以关键是优化算法。如下图,我们可以把题意理解成是每次把数组的第一个元素移到最后然后求出当前状态的point,最后得出最大的point出现的时机。point是根据元素的值减去元素所在下标得来的,只有元素的值小于或者等于下标才能得到point。接下来,我们再观察每次移动数组的第一个元素后的得失point情况,首先只有一个可能会得到point的,那就是移动的元素小于数组末尾的下标;对于失去point的情况,除了第一个元素外,其他的元素相当于是右移,而右移是一个下标减小的过程,元素的值不变,而下标不断减小,所以在平移过程中,原先能得到point的元素可能会变得得不到point,而原先就等不到的不管平移到哪里都还是得不到。发现这些规律后,结题的方法就呼之欲出了。首先,遍历数组,得到所有得到point的元素数量count,以及一个包括元素值和元素下标差值v以及v出现的次数的字典(这里我用的是数组,可能直接通过下标查找),显然所有v出现的次数是等于point的元素数量的。接下来就是关键了,再次遍历数组,每移动一个元素,用count减去失去point元素的数量,再加上移动到最后的元素是否能得到point的数量,即是这次移动后的point值,直到所有元素都移动到最后,即可求出最大的point。还有一点要注意的是,第一个元素移到数组最后时,如果能得到point,需要把这个元素加到字典中去,因为随着数组的移动,这个元素后面有可能又会失去point。

代码如下:

class Solution(object):
def bestRotation(self, A):
"""
:type A: List[int]
:rtype: int
"""
l = []
K = 0
highest = 0
val = [0 for x in range(len(A)*2)]
for i in range(len(A)):
if A[i] - i <= 0:
val[-1*(A[i] -i)] += 1
highest += 1
count = highest
for i in range(1,len(A)):
count -= val[i-1] #每移动一个元素,用count减去失去point元素的数量
val[i-1] = 0
t = A[i-1] - (len(A) -1)
if t <= 0:
count += 1 #再加上移动到最后的元素是否能得到point的数量
val[-1*t+i] += 1 #关键点:要把平移的元素重新加入字典,因为后面可能会失去point
if highest <count:
highest = count
K = i
return K

最新文章

  1. Thrift简单实践
  2. GCD封装的个人理解和应用
  3. tomcat JNDI 设置
  4. 在Hadoop-2.2.0集群上安装 Hive-0.13.1 with MySQL
  5. openfire过滤脏话插件,控制消息是否发送
  6. Apache XAMPP Fails to start under Windows XP
  7. oracle分组-神奇的cube和rollup
  8. OpenCV——去雾
  9. vscode实现vue.js项目的过程
  10. GUI 设计
  11. Redis无法启动
  12. .net core mvc 错误信息显示 ModelState.AddModelError
  13. 超级账本Hyperledge的kafka共识算法里的Topic 与 Partition
  14. c# 值类型与引用类型的传参(形参与实参)
  15. thinkphp 百度编辑器和layer简单用法
  16. Nginx 访问日志分析
  17. 三羊献瑞|2015年蓝桥杯B组题解析第三题-fishers
  18. table maker&#39;s delimma
  19. 小技巧textbox的行数
  20. IEEEXtreme 极限编程大赛题解

热门文章

  1. 开发一个Flink应用
  2. nslookup的安装方法
  3. FacertGrid()的使用
  4. centos7 无法启动网络(service network restart)错误解决办法(转)
  5. Monkey常用命令详解
  6. Labview 错误1400-打包库封装类时将对类重命名导致
  7. 基于TCP和UDP的socket
  8. 用Java构建一个简单的WebSocket聊天室
  9. 模板 - 无旋Treap
  10. oracle数据库中的存储过程