为什么此解决方案不会陷入无限循环?

时间:2019-06-12 19:16:54

标签: python arrays

我在HackerRank(https://www.hackerrank.com/challenges/minimum-swaps-2/problem)上解决了最小掉期2阵列挑战。我的解决方案将在较大的数组上超时,因此我返回到重构代码。我遇到了新的解决方案,几乎在我提交该解决方案后就意识到这一点。但是,它确实..完美,但是我发疯了试图找出原因。至少,为什么它不陷入无限的while循环中,来回反复交换两个数组值?撇开明显的地方,让我们说它确实突然退出了循环,如果我们正在寻找最小交换数量?我在代码的不同位置添加了打印语句,以尝试了解正在发生的事情并亲自理解它,但它们只会增加混乱。有人可以引导我理解我荒谬的天才逻辑吗?还是这是fl幸?

#!/bin/python3

import math
import os
import random
import re
import sys

# Complete the minimumSwaps function below.
def minimumSwaps(arr):
    swaps = 0

    for x in range(0, n - 1):
        while arr[x] != x + 1:
            arr[arr[x] - 1], arr[x] = arr[x], arr[arr[x] - 1]
            swaps += 1

    return swaps


if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    n = int(input())

    arr = list(map(int, input().rstrip().split()))

    res = minimumSwaps(arr)

    fptr.write(str(res) + '\n')

    fptr.close()

2 个答案:

答案 0 :(得分:1)

只要您想按照自己的步骤进行操作

                             list  swap_index_1  swap_index_2
0  [7, 9, 6, 4, 2, 5, 1, 3, 8, 0]           NaN           NaN
1  [1, 9, 6, 4, 2, 5, 7, 3, 8, 0]           0.0           0.0
2  [1, 8, 6, 4, 2, 5, 7, 3, 9, 0]           1.0           7.0
3  [1, 3, 6, 4, 2, 5, 7, 8, 9, 0]           1.0           2.0
4  [1, 6, 3, 4, 2, 5, 7, 8, 9, 0]           1.0           5.0
5  [1, 5, 3, 4, 2, 6, 7, 8, 9, 0]           1.0           4.0
6  [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]           1.0           1.0

from random import shuffle
import pandas as pd
steps = []


def log(arr, s1, s2):
    steps.append(dict(list=arr.copy(), swap_index_1=s1, swap_index_2=s2))


n = 10
arr = list(range(n))
shuffle(arr)

swaps = 0

log(arr, None, None)

for x in range(0, n - 1):
        while arr[x] != x + 1:
            arr[arr[x] - 1], arr[x] = arr[x], arr[arr[x] - 1]
            swaps += 1

            log(arr, x, arr[x] - 1)

steps = pd.DataFrame(steps)
print(steps)

答案 1 :(得分:0)

您的while条件检查当前元素是否在正确的位置:
while arr[x] != x + 1:

循环中的每次迭代都将x位置的值移动到其正确位置arr [x] -1。因此,while中的每次迭代都会纠正一个元素的位置。请参见下面的示例:

>>> i = 0
>>> a
[9, 1, 3, 10, 8, 5, 6, 2, 7, 4]
>>> #first iteration
>>> a[a[i]-1], a[i] = a[i], a[a[i] - 1]
>>> a
[7, 1, 3, 10, 8, 5, 6, 2, 9, 4]
>>> #second iteration
>>> a[a[i]-1], a[i] = a[i], a[a[i] - 1]
>>> a
[6, 1, 3, 10, 8, 5, 7, 2, 9, 4]

第一次迭代将9移到数组的第9个位置(索引8),第一个位置变为7。 第二次迭代将7移到数组的第7个位置(索引6),第一个位置变为6。

我希望这足够清楚:)