问题来自代码斗争,其中指出:无数个盒子排成一行并从左到右编号。左边的第一个框是 数字1,下一个方框是2号等,n个球放在n个盒子里,每个盒子只能有一个球。 你想组织球,所以你决定将所有的球安排在一起。他们应该占有一席之地 连续的一套盒子。你可以拿一个球并一次移动到一个空盒子里。
给定一个阵列球,指示放置球的盒子的数量,找到最小数量 需要采取行动来组织球。
实施例
对于球= [6,4,1,7,10],输出应为 球重新排列(球)= 2。
在这个例子中,将球排列在彼此旁边所需的最小移动次数是2.你可以移动 在方框1到方框5中的球和方框10中的球到方框8(或方框3)。
目前我的代码是:
def ballsRearranging(balls):
ballsLength = len(balls)
partial = ballsLength//2 #INITIALLY SET TO HALF
setBalls = set(balls)
sortedBalls = sorted(balls)
minimum = 1000000
#####CHECK IF ITS ALREADY ORGANIZED
#####FIRST NUM PLUS LENGTH - 1 IS EQUAL TO THE LAST NUM
if sortedBalls[0]+ballsLength-1 == sortedBalls[-1]:
return 0
for i,num in enumerate(sortedBalls):
#####NO NEED TO GO PASS HALF WAY SINCE THAT AUTOMATICALLY MEANS HALF WILL BE OUT OF RANGE
#####THIS VALUE DYNAMICALLY CHANGES TO THE SMALLEST FRACTION OF OUT OF RANGE FOUND
if i >= partial:
break
#####IF WE TAKE THIS NUM AS THE BEGINNING, ORDERED BALLS WILL GO UP TO THE RANGE RNG
rng = range(num,num+ballsLength)
#####BALLS ALREADY IN THE RANGE RNG, WE WONT BE MOVING THESE BALLS
inRange = setBalls & set(rng)
#####BALLS NOT IN RANGE, EACH WILL BE REQUIRED TO MOVE
#####THE LENGTH OF THIS WILL BE THE NUMBER OF MOVES REQUIRED
outRange = setBalls - set(rng)
lenOutRange = len(outRange)
if lenOutRange < minimum:
minimum = lenOutRange
partial = 100*(lenOutRange/ballsLength) #UPDATE THE PARTIAL VALUE
这样可以正常工作,但目前在隐藏测试中超时时限为4秒。基本上我的算法从最小的数字到给定数组的特定部分(分数)。它检查原始集合与给定范围相交的位置。无论哪个具有最少量的超出范围的项目,将是最小数量的更改/重新排列。想知道什么是更好的算法,最好是在python中。
答案 0 :(得分:1)
首先,你在你的范围和设置结构上花了很多时间。退出检查实际的球位置和空盒子。你所需要的只是移动的数量,而不是要移动的实际球。
例如,给定[1,2,100,103,104,106,9998,9999]之类的东西,你不在乎这四个异常值是什么,或者哪些方框是空的在低100范围内。您所需要的只是数量,4。
解决方案简化为更简单的方法:
Realm Browser
如果你对此有点顽固,可以将其减少到一行。
答案 1 :(得分:1)
此代码小心计算O(n log n)时间内的结果。或者如果球已经排序,则在O(n)时间运行。
它使用卡特彼勒算法:对于每个j,索引到排序的球阵列中,i递增,直到它包含在索引j处的球的n-1
内的第一个球。这样可以很容易地计算以第j球结束的范围内的球数。
def balls_rearranging(balls):
balls.sort()
best = 0
i = 0
for j in xrange(len(balls)):
while balls[i] <= balls[j] - len(balls):
i += 1
best = max(best, j - i + 1)
return len(balls) - best
print balls_rearranging(range(0, 10000000, 2))
答案 2 :(得分:0)
paul-hankin提供的代码的Java版本
int ballsRearranging(int[] balls) {
Arrays.sort(balls); // sort the array
int i = 0;
int j = 0;
int max = 0;
for(j = 0; j < balls.length;j++) {
while(balls[i] <= balls[j] - balls.length) {
i++;
}
max = Math.max(max,j-i+1);
}
return balls.length - max;}