How do you check if one array is a subsequence of another?

后端 未结 4 1134
南旧
南旧 2020-12-21 09:44

I\'m looking to explore different algorithms, both recursive and dynamic programming, that checks if one arrayA is a subsequence of arrayB. For example,

arra         


        
相关标签:
4条回答
  • 2020-12-21 10:20

    As dasblinkenlight has correctly said(and i could not have phrased it better than his answer!!) a greedy approach works absolutely fine. You could use the following pseudocode (with just a little more explanation but totally similar to what dasblinkenlight has written)which is similar to the merging of two sorted arrays.

    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*/
    

    Time Complexity is O(|A|+|B|) in the worst case, where |A| & |B| are the number of elements present in Arrays A and B respectively. Thus you get a linear complexity.

    0 讨论(0)
  • 2020-12-21 10:29

    Here is an example in 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
    
    0 讨论(0)
  • 2020-12-21 10:30

    Since you must match all elements of arrayA to some elements of arrayB, you never need to backtrack. In other words, if there are two candidates in arrayB to match an element of arrayA, you can pick the earliest one, and never retract the choice.

    Therefore, you do not need DP, because a straightforward linear greedy strategy will work:

    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;
    }
    
    0 讨论(0)
  • 2020-12-21 10:35

    As @sergey mentioned earlier, there is no need to do backtracking in this case. Here just another Python version to the problem:

    >>> 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
    >>> 
    
    0 讨论(0)
提交回复
热议问题