如何检查一个数组是否是另一个数组的子序列?

时间:2015-10-16 16:10:15

标签: algorithm recursion dynamic-programming subsequence

我正在寻找不同的算法,包括递归和动态编程,检查一个arrayA是否是arrayB的子序列。例如,

arrayA = [1, 2, 3] 
arrayB = [5, 6, 1, 7, 2, 9, 3]

thus, arrayA is indeed a subsequence of arrayB. 

我尝试了一些不同的搜索,但我似乎只能找到算法来计算最长的增长子序列。

6 个答案:

答案 0 :(得分:10)

由于您必须将arrayA所有元素与arrayB的某些元素相匹配,因此您永远不需要回溯。换句话说,如果arrayB中有两个候选人匹配arrayA的元素,您可以选择最早的一个,并且永远不会撤消选择。

因此,您不需要DP,因为直接的线性贪婪策略将起作用:

bool isSubsequence(int[] arrayA, int[] arrayB) {
    int startIndexB = 0;
    foreach (int n in arrayA) {
        int next = indexOf(arrayB, startIndexB , n);
        if (next == NOT_FOUND) {
            return false;
        }
        startIndexB = next+1;
    }
    return true;
}

答案 1 :(得分:2)

正如dasblinkenlight正确地说的那样(我不能比他的回答更好地表达它!)一种贪婪的方法非常好。你可以使用下面的伪代码(只有更多的解释,但与dasblinkenlight写的完全类似),这类似于两个有序数组的合并。

A = {..}
B = {..}

j = 0, k = 0
/*j and k are variables we use to traverse the arrays A and B respectively*/

for(j=0;j<A.size();){

    /*We know that not all elements of A are present in B as we 
      have reached end of B and not all elements of A have been covered*/
    if(k==B.size() && j<A.size()){
        return false;
    }

    /*we increment the counters j and k both because we have found a match*/            
    else if(A[j]==B[k]){
        j++,k++;
    }

   /*we increment k in the hope that next element may prove to be an element match*/        
    else if(A[j]!=B[k]){
        k++;
    }
}

return true; /*cause if we have reached this point of the code 
               we know that all elements of A are in B*/

在最坏的情况下,时间复杂度为O(| A | + | B |),其中| A | &安培; | B |是数组AB中分别存在的元素数。因此,您将获得线性复杂性。

答案 2 :(得分:1)

正如@sergey前面提到的,在这种情况下无需进行回溯。 这里只是该问题的另一个Python版本:

>>> A = [1, 2, 3]
>>> B = [5, 6, 1, 7, 8, 2, 4, 3]
>>> def is_subsequence(A, B):
    it = iter(B)
    return all(x in it for x in A)

>>> is_subsequence(A, B)
True
>>> is_subsequence([1, 3, 4], B)
False
>>> 

答案 3 :(得分:0)

这是Ruby中的一个例子:

def sub_seq?(a_, b_)
  arr_a = [a_,b_].max_by(&:length);
  arr_b = [a_,b_].min_by(&:length);
  arr_a.select.with_index do |a, index|
    arr_a.index(a) &&
    arr_b.index(a) &&
    arr_b.index(a) <= arr_a.index(a)
  end == arr_b
end

arrayA = [1, 2, 3] 
arrayB = [5, 6, 1, 7, 2, 9, 3]

puts sub_seq?(arrayA, arrayB).inspect #=> true

答案 4 :(得分:0)

这是一个python示例:

def is_sublist(a,b):
    idx_b = 0
    for v in a:
        try:
            b[idx_b:].index(v)
        except ValueError:
            return False
        idx_b += 1
    return True

答案 5 :(得分:0)

这是GOLAN中的一个例子...

func subsequence(first, second []int) bool {
k := 0
for i := 0; i < len(first); i++ {
    j := k
    for ; j < len(second); j++ {
        if first[i] == second[j] {
            k = j + 1
            break
        }
    }
    if j == len(second) {
        return false
    }
}
return true
}

func main(){
      fmt.Println(subsequence([]int{1, 2, 3}, []int{5, 1, 3, 2, 4}))
}