给定两个数组,如何检查一个数组是否是另一个数组的循环排列?
例如,给定a = [1, 2, 3, 1, 5]
,b = [3, 1, 5, 1, 2]
和c = [2, 1, 3, 1, 5]
我们a
和b
是循环排列但c
不是两者的循环置换。
注意:数组可能有重复的元素。
答案 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;
}
}