HackerRank挑战咨询:整数数组排序移位次数计算方法
计算数组排序所需移位次数的简便解法
嘿,作为刚接触编程的新手,碰到这种问题太正常啦!我来给你拆解清楚这个问题,用最简单的思路搞定它~
首先咱们得明确题目里的「移位」指的是什么——通常这类HackerRank的题目说的是循环移位:要么把数组第一个元素移到末尾(左移一次),要么把最后一个元素移到开头(右移一次)。咱们的目标是找到最少的移位次数,让数组变成完全有序的状态。
最常见的场景:数组是旋转后的有序数组
这类题是HackerRank里的高频题,比如给你的数组是[3,4,5,1,2],它其实是有序数组[1,2,3,4,5]左移3次得到的。这种情况解法超级简单:
- 找到数组中最小元素的索引,这个索引值就是需要左移的次数(如果题目要求右移次数,就用数组总长度减去这个索引值)。
- 举个例子:
[3,4,5,1,2]里最小元素是1,它的索引是3,所以左移3次就能得到有序数组;如果要求右移次数,就是5-3=2次。
代码示例(Python)
def count_min_shifts(arr): # 先判断数组是否已经有序 if arr == sorted(arr): return 0 # 找到最小元素的索引 min_value = min(arr) shift_count = arr.index(min_value) return shift_count # 返回左移次数,右移次数用 len(arr) - shift_count
如果是任意无序数组的情况
如果你的数组是完全乱的(比如[4,2,5,1,3]),那其实循环移位不一定能让它变成有序数组——这时候可能题目描述的「移位」是指相邻元素交换?不过你提到的是移位,大概率还是上面的旋转有序数组场景。
要是真的遇到任意数组需要通过循环移位变有序的情况,核心思路是:
- 先得到排序后的目标数组
- 把原数组拼接成两倍长度(比如
arr + arr),这样就能模拟循环移位的所有可能情况 - 在这个拼接后的数组里,找到最长的一段连续元素,正好和排序后数组的前缀完全匹配
- 移位次数就是数组总长度减去这段最长匹配的长度
对应代码示例(Python)
def count_shifts_for_any_arr(arr): sorted_arr = sorted(arr) n = len(arr) if arr == sorted_arr: return 0 # 拼接数组模拟循环移位 doubled_arr = arr + arr max_match_length = 0 current_match = 0 for num in doubled_arr: if current_match < n and num == sorted_arr[current_match]: current_match += 1 max_match_length = max(max_match_length, current_match) else: # 重新开始匹配 current_match = 1 if num == sorted_arr[0] else 0 return n - max_match_length
这个方法的好处是不需要真的去模拟每一次移位操作,只需要通过一次遍历就能算出结果,效率很高。
内容的提问来源于stack exchange,提问作者user135716
相关产品推荐
相关产品推荐

