Larry's Array 解题思路及过程

先甩链接https://www.hackerrank.com/challenges/larrys-array

首先想到的一个思路是:从数列中找最小值并确定最小值的位置

1. 如果最小值的位置在数列的第一位,则在1..n中继续找次小值所在的位置(可以理解为移除首位的最小值,然后在剩余数列中寻找最小值);

2. 如果最小值的位置在数列的第二位,则选取0..3三个数组成子数列进行一次轮转将最小值移至首位

3. 如果最小值的位置在数列的第二位之后,则选取最小值之前的两个数与最小值一起组成子数列进行两次轮转将最小值移至子数列的第一位,然后继续循环进行操作

4. 当剩余数列的长度不足3时,退出循环,并核对结果数列是否是升序排序,是输出YES,否输出NO

 

题目的输入条件:

第一行:测试案例的数量

第二行:数列的数字个数

第三行:数列的各个数字,使用一个空格进行分隔

 

实现代码如下:

 1 # 轮转3个数的列表 0<-1, 1<-2, 2<-0
 2 def rotate(p_arr_sub):
 3     arr_sub_r = p_arr_sub
 4     temp = arr_sub_r[0]
 5     arr_sub_r[0] = arr_sub_r[1]
 6     arr_sub_r[1] = arr_sub_r[2]
 7     arr_sub_r[2] = temp
 8     return arr_sub_r
 9 
10 t = int(input().strip())
11 
12 for a0 in range(t):
13     n = int(input().strip())
14     arr = [int(arr_temp) for arr_temp in input().strip().split(' ')]
15 
16     # 列表的起点序号
17     begin_index = 0
18 
19     while begin_index < n - 2:
20         # 获取最小值在列表中的位置序号
21         min_value_index = arr.index(min(arr[begin_index:]))
22         # 最小值位置序号与列表起点相同, 则说明无需进行轮转
23         # 列表起点位置后移一位
24         if min_value_index == begin_index:
25             begin_index += 1
26         # 最小值位置在起点序号之后一位, 则需要进行一次轮转
27         elif min_value_index == begin_index + 1:
28             arr_sub = rotate(arr[begin_index:begin_index+3])
29             arr[begin_index:begin_index + 3] = arr_sub
30         # 最小值位置在起点序号之后两位以上, 则获取最小值之前的两位与最小值一起构成一个长度为3的子列表进行两次轮转
31         else:
32             arr_sub = rotate(rotate(arr[min_value_index-2:min_value_index+1]))
33             arr[min_value_index-2:min_value_index+1] = arr_sub
34 
35     if sorted(arr) == arr:
36         print("YES")
37     else:
38         print("NO")

获得结果如下:

 一共20个测试案例前10个都正常通过,后10个全部超时,拿到最后一个案例的输入与期望输出在本地进行测试后发现结果是正确的,所以剩下的事情就是如何进行效率的优化。

 

重新分析了一下题目,输出要求是YES or NO,所以并不一定需要进行实际的轮转操作,参照https://en.wikipedia.org/wiki/Parity_of_a_permutation的思路最终的解决代码如下:

 1 t = int(input().strip())
 2 
 3 for a0 in range(t):
 4     n = int(input().strip())
 5     arr = [int(arr_temp) for arr_temp in input().strip().split(' ')]
 6     
 7     inversions = 0
 8     for i in range(n-1):
 9         for j in range(i+1, n):
10             if arr[i] > arr[j]:
11                 inversions += 1
12     
13     if inversions % 2 == 0:
14         print("YES")
15     else:
16         print("NO")

 

转载于:https://www.cnblogs.com/rossmary/p/5620234.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值