Python 重新排列给定数字数组的更快算法是什么
这个问题来自于代码战,它说:无限多的盒子排成一行,从左到右编号。左边的第一个框是 1号,下一个盒子是2号,等等。n个球放在n个盒子里,每个盒子只能有一个球。 你想把球组织起来,所以你决定把所有的球排列在一起。他们应该占据一个位置 连续的一组盒子。你可以拿一个球,用一个动作把它移动到一个空盒子里 给定一个指示放置球的盒子数量的球数组,找出最小数量的球 组织球所需的动作 范例 对于balls=[6,4,1,7,10],输出应为 球数=2 在本例中,排列相邻球所需的最小移动次数为2。你可以把它移走 框1至框5中的球以及框10至框8(或框3)中的球 目前我的代码是:Python 重新排列给定数字数组的更快算法是什么,python,algorithm,Python,Algorithm,这个问题来自于代码战,它说:无限多的盒子排成一行,从左到右编号。左边的第一个框是 1号,下一个盒子是2号,等等。n个球放在n个盒子里,每个盒子只能有一个球。 你想把球组织起来,所以你决定把所有的球排列在一起。他们应该占据一个位置 连续的一组盒子。你可以拿一个球,用一个动作把它移动到一个空盒子里 给定一个指示放置球的盒子数量的球数组,找出最小数量的球 组织球所需的动作 范例 对于balls=[6,4,1,7,10],输出应为 球数=2 在本例中,排列相邻球所需的最小移动次数为2。你可以把它移走 框
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
def球排列(球):
球长=长度(球)
partial=ballsLength//2#最初设置为一半
立根=设置(球)
分拣球=分拣(球)
最小值=1000000
#####检查它是否已经组织好了
#####第一个数值加上长度-1等于最后一个数值
如果sortedBalls[0]+ballsLength-1==sortedBalls[-1]:
返回0
对于i,枚举中的num(sortedBalls):
#####无需中途通过,因为这自动意味着一半将超出范围
#####此值动态更改为找到的超出范围的最小部分
如果i>=部分:
打破
#####如果我们以这个数字作为开始,有序的球将上升到范围RNG
rng=范围(num,num+ballsLength)
#####球已经在射程RNG内,我们不会移动这些球
inRange=立根和设置(rng)
#####球不在范围内,每个球都需要移动
#####这个长度将是所需的移动次数
超出范围=立根-设置(rng)
lenOutRange=len(超出范围)
如果lenOutRange<最小值:
最小值=超出范围
部分=100*(lenOutRange/ballsLength)#更新部分值
这可以正常工作,但目前在隐藏测试的时间限制为4s时超时。基本上,我的算法是从最小的数到给定数组的特定部分(分数)。它检查原始集合与给定范围相交的位置。以超出范围的项目数量最少的为准,将是进行更改/重新安排的最小数量。我想知道更好的算法是什么,最好是python。首先,你在范围和集合构造上花费了很多时间。停止检查球的实际位置和空框。你所需要的只是移动的数量,而不是实际要移动的球 例如,给定[1,2,100,103,104,106,9998,9999]之类的值,您不关心这四个异常值是什么,也不关心在低100范围内哪些框是空的。你所需要的只是数量,4 解决方案简化为一些更简单的问题:
size = len(balls)
balls.sort()
for box in balls:
# How many balls are in the range box : box+size-1 ?
# retain the maximum of these values
return size - maximum # number of empty boxes in that range
如果你对此有点固执,你可以把它简化成一行。这段代码很小心地用O(n logn)时间计算结果。或者,如果球已经被分类,这将在O(n)时间内运行 它使用caterpillar算法:对于索引到已排序球数组中的每个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))
def balls\u重新排列(balls):
balls.sort()
最佳值=0
i=0
对于X范围内的j(透镜(球)):
而balls[i]是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;}
int balls排列(int[]balls){
Arrays.sort(balls);//对数组进行排序
int i=0;
int j=0;
int max=0;
对于(j=0;j while(balls[i]当前算法的最大O复杂性是什么?我建议您将此移到CodeReview.StackExchange.com;StackOverflow通常用于非工作代码。如需帮助,请发布长期运行测试用例的驱动程序代码。打印balls\u重新排列(范围(0,10000000,2))
是一个很好的测试用例。