python - 检查由N个整数组成的数组是否是一个排列

时间:2016-10-24 00:35:27

标签: python

我正在分析routine,它检查N个整数的数组是否是一个排列(包含从1到N的每个元素的序列)。

 我是python的新手。我无法掌握这个例程如何得到正确的答案。任何人都可以解释循环背后的逻辑吗?特别是使用counter[element-1]

 计数器是否是A的每个元素的内置函数?默认情况下,A的元素的counter[element-1]引用位置/值是否为,因为循环是在数组上定义的?

A=[4,1,3,2]

    def solution(A):
        counter = [0]*len(A)
        limit = len(A)
        for element in A:
            if not 1 <= element <= limit:
                return 0
            else:
                if counter[element-1] != 0:
                    return 0
                else:
                    counter[element-1] = 1

        return 1

更新 我修改了代码以查看循环中使用的值,例如

def solution(A):
    counter = [0]*len(A)
    limit = len(A)
    for element in A:
        if not 1 <= element <= limit:
            print element
            print 'outside'
            return 0
        else:
            if counter[element-1] != 0:
                print 'element %d' % element
                print [element-1]
                print counter[element-1]
                return 0
            else:
                counter[element-1] = 1
                print 'element %d' % element
                print [element-1]
                print counter[element-1]

    return 1

给了我

element 4
[3]
1
element 1
[0]
1
element 3
[2]
1
element 2
[1]
1
1

我仍然没有得到逻辑。例如,对于第一个元素,为什么[3]给出1?

2 个答案:

答案 0 :(得分:2)

实际上是一种狡猾的算法。

输入是一个长度为N的序列。

输入的每个元素都被假定为一个整数(如果不是,比较或索引将抛出异常)。

counter是一个标志数组 - 长度为N

  • 不允许[1,N]范围之外的整数
  • 不允许重复(看看它是如何完成的)

你现在可以证明两种条件保持正确的唯一方法是使序列成为一种排列吗?

答案 1 :(得分:2)

代码背后的想法是双重的。列表[1,2,...,N]的排列有两个属性。它只有1到N之间的元素,每个元素只在列表中出现一次。 我会尝试在代码中逐一解释这个想法。

def solution(A):
    counter = [0]*len(A)
    limit = len(A)

例如,假设一个列表[1,3,2]。 counter被初始化为大小为len(A)= 3的零列表。每个0对应于列表中的一个元素

for element in A:
        if not 1 <= element <= limit:
            return 0

这部分条件是最简单的条件。如果元素不在此范围内,则列表不能是[1,2,... N]的置换。例如,[1,3,2]是[1,2,3]的排列,但[1,6,2]不是。

 else:
            if counter[element-1] != 0:
                return 0
            else:
                counter[element-1] = 1

下一部分与每个术语的唯一性有关。 if检查number = element是否已通过此循环。第二个else确保标记了此数字,因此如果在下一次迭代中找到重复的数字,if将为真并返回0。 例如,对于列表[1,2,2]。前2个不会触发if,而第二个2会触发它,返回0.另一方面,[1,3,2]永远不会触发if。 如果所有数字都通过了这个条件,那么这两个属性都是真的,列表就是一个排列。