How to find minimal-length subsequence that contains all element of a sequence

后端 未结 7 1435
无人共我
无人共我 2021-02-01 07:29

Given a sequence such as S = {1,8,2,1,4,1,2,9,1,8,4}, I need to find the minimal-length subsequence that contains all element of S (no duplicates, order does n

7条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-01 07:59

    Here is an algorithm that requires O(N) time and O(N) space. It is similar to that one by Grigor Gevorgyan. It also uses an auxiliary O(N) array of flags. The algorithm finds the longest subsequence of unique elements. If bestLength < numUnique then there is no subsequence containing all unique elements. The algorithm assumes that the elements are positive numbers and that the maximal element is less than the length of the sequence.

    bool findLongestSequence() {
        // Data (adapt as needed)
        const int N = 13;
        char flags[N];
        int a[] = {1,8,2,1,4,1,2,9,1,8,1,4,1};
    
        // Number of unique elements
        int numUnique = 0;
        for (int n = 0; n < N; ++n) flags[n] = 0; // clear flags
        for (int n = 0; n < N; ++n) {
            if (a[n] < 0 || a[n] >= N) return false; // assumptions violated 
            if (flags[a[n]] == 0) {
                ++numUnique;
                flags[a[n]] = 1;
            }
        }
    
        // Find the longest sequence ("best")
        for (int n = 0; n < N; ++n) flags[n] = 0; // clear flags
        int bestBegin = 0, bestLength = 0;
        int begin = 0, end = 0, currLength = 0;
        for (; begin < N; ++begin) {
            while (end < N) {
                if (flags[a[end]] == 0) {
                    ++currLength;
                    flags[a[end]] = 1;
                    ++end;
                }
                else {
                    break; // end-loop
                }
            }
            if (currLength > bestLength) {
                bestLength = currLength;
                bestBegin = begin;
            }
            if (bestLength >= numUnique) {
                break; // begin-loop
            }
            flags[a[begin]] = 0; // reset
            --currLength;
        }
    
        cout << "numUnique = " << numUnique << endl;
        cout << "bestBegin = " << bestBegin << endl;
        cout << "bestLength = " << bestLength << endl;
        return true; // longest subseqence found 
    }
    

提交回复
热议问题