检查两个数组是否为循环排列

时间:2011-05-24 02:19:39

标签: algorithm language-agnostic cycle permutation

给定两个数组,如何检查一个数组是否是另一个数组的循环排列?

例如,给定a = [1, 2, 3, 1, 5]b = [3, 1, 5, 1, 2]c = [2, 1, 3, 1, 5]我们ab是循环排列但c不是两者的循环置换。

注意:数组可能有重复的元素。

4 个答案:

答案 0 :(得分:21)

这里的标准技巧是将其中一个数组与自身连接起来,然后尝试在连接数组中找到第二个数组。

例如,与自身连接的'a'是:

[1,2,3,1,5,1,2,3,1,5]

因为你从第3个元素开始看到这个数组中的'b',所以a和b是循环排列。

答案 1 :(得分:8)

如果A和B是彼此的循环排列,A将在双倍列表BB中找到(与AA中的B一样)。

答案 2 :(得分:8)

处理大量数据的有效方法是将每个数据转换为“规范”形式,然后比较它们是否相等。对于这个问题,您可以选择所有旋转排列的规范形式,即“最小排序”。

因此'a'和'b'的规范形式是[1,2,3,1,5],它们是相同的,因此它们是非循环排列。

'c'的规范形式是[1,3,1,5,2],这是不同的。

答案 3 :(得分:0)

这是一种简单的临时方法,用于找出具有O(n)时间复杂度的循环置换。

a = [1,2,3,1,5],b = [3,1,5,1,2]

在[]中找到b [0]的索引,假设索引是' x'。然后开始     在数组中导航。 a []从索引' x'开始和b []     从' 0开始。这样它们都必须具有相同的值。如果     不,它们不是循环的。      这是示例代码。

 public class CyclicPermutation {

    static char[] arr = { 'A', 'B', 'C', 'D' };
    static char[] brr = { 'C', 'D', 'K', 'B' };
    boolean dec = false;

    public static void main(String[] args) {
        boolean avail = true;
        int val = getFirstElementIndex(brr[0]);
        if(val ==Integer.MIN_VALUE){
            avail = false; 
            return;
            }

        for (int i = val, j = 0; j <= brr.length-1; ) {
            if (i > arr.length-1) {
                i = 0;
            }
            if (arr[i] == brr[j]) {
                i++;

                j++;

            } else {
                avail = false;
                System.out.println(avail);
                return;
            }


        }

   System.out.println(avail);
    }

    public static int getFirstElementIndex(char c) {

        for (int i = 0; i <= arr.length; i++) {
            if (arr[i] == c) {
                return i;
            }
        }
        return Integer.MIN_VALUE;
    }


}