Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 重新排列给定数字数组的更快算法是什么_Python_Algorithm - Fatal编程技术网

Python 重新排列给定数字数组的更快算法是什么

Python 重新排列给定数字数组的更快算法是什么,python,algorithm,Python,Algorithm,这个问题来自于代码战,它说:无限多的盒子排成一行,从左到右编号。左边的第一个框是 1号,下一个盒子是2号,等等。n个球放在n个盒子里,每个盒子只能有一个球。 你想把球组织起来,所以你决定把所有的球排列在一起。他们应该占据一个位置 连续的一组盒子。你可以拿一个球,用一个动作把它移动到一个空盒子里 给定一个指示放置球的盒子数量的球数组,找出最小数量的球 组织球所需的动作 范例 对于balls=[6,4,1,7,10],输出应为 球数=2 在本例中,排列相邻球所需的最小移动次数为2。你可以把它移走 框

这个问题来自于代码战,它说:无限多的盒子排成一行,从左到右编号。左边的第一个框是 1号,下一个盒子是2号,等等。n个球放在n个盒子里,每个盒子只能有一个球。 你想把球组织起来,所以你决定把所有的球排列在一起。他们应该占据一个位置 连续的一组盒子。你可以拿一个球,用一个动作把它移动到一个空盒子里

给定一个指示放置球的盒子数量的球数组,找出最小数量的球 组织球所需的动作

范例

对于balls=[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
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;jwhile(balls[i]当前算法的最大O复杂性是什么?我建议您将此移到CodeReview.StackExchange.com;StackOverflow通常用于非工作代码。如需帮助,请发布长期运行测试用例的驱动程序代码。
打印balls\u重新排列(范围(0,10000000,2))
是一个很好的测试用例。