longest increasing subsequence(O(nlogn))

前端 未结 8 829
花落未央
花落未央 2020-12-07 11:10

LIS:wikipedia

There is one thing that I can\'t understand:

why is X[M[i]] a non-decreasing sequence?

8条回答
  •  囚心锁ツ
    2020-12-07 11:50

    This is the O(n*lg(n)) solution from The Hitchhiker’s Guide to the Programming Contests (note: this implementation assumes there are no duplicates in the list):

    set st;
    set::iterator it;
    st.clear();
    for(i=0; i

    To account for duplicates one could check, for example, if the number is already in the set. If it is, ignore the number, otherwise carry on using the same method as before. Alternatively, one could reverse the order of the operations: first remove, then insert. The code below implements this behaviour:

    set st;
    set::iterator it;
    st.clear();
    for(int i=0; i

    The second algorithm could be extended to find the longest increasing subsequence(LIS) itself by maintaining a parent array which contains the position of the previous element of the LIS in the original array.

    typedef pair IndexValue;
    
    struct IndexValueCompare{
        inline bool operator() (const IndexValue &one, const IndexValue &another){
            return one.second < another.second;
        }
    };
    
    vector LIS(const vector &sequence){
        vector parent(sequence.size());
        set s;
        for(int i = 0; i < sequence.size(); ++i){
            IndexValue iv(i, sequence[i]);
            if(i == 0){
                s.insert(iv);
                continue;
            }
            auto index = s.lower_bound(iv);
            if(index != s.end()){
                if(sequence[i] < sequence[index->first]){
                    if(index != s.begin()) {
                        parent[i] = (--index)->first;
                        index++;
                    }
                    s.erase(index);
                }
            } else{
                parent[i] = s.rbegin()->first;
            }
            s.insert(iv);
        }
        vector result(s.size());
        int index = s.rbegin()->first;
        for(auto iter = s.rbegin(); iter != s.rend(); index = parent[index], ++iter){
            result[distance(iter, s.rend()) - 1] = sequence[index];
        }
        return result;
    }
    

提交回复
热议问题