#include #include #include #include template struct Node { T value; Node* prev_node; }; template Container lis(const Container& values) { using E = typename Container::value_type; using NodePtr = Node*; using ConstNodePtr = const NodePtr; std::vector pileTops; std::vector> nodes(values.size()); // sort into piles auto cur_node = std::begin(nodes); for (auto cur_value = std::begin(values); cur_value != std::end(values); ++cur_value, ++cur_node) { auto node = &*cur_node; node->value = *cur_value; // lower_bound returns the first element that is not less than 'node->value' auto lb = std::lower_bound(pileTops.begin(), pileTops.end(), node, [](ConstNodePtr& node1, ConstNodePtr& node2) -> bool { return node1->value < node2->value; }); if (lb != pileTops.begin()) node->prev_node = *std::prev(lb); if (lb == pileTops.end()) pileTops.push_back(node); else *lb = node; } // extract LIS from piles // note that LIS length is equal to the number of piles Container result(pileTops.size()); auto r = std::rbegin(result); for (NodePtr node = pileTops.back(); node != nullptr; node = node->prev_node, ++r) *r = node->value; return result; } template void show_lis(const Container& values) { auto&& result = lis(values); for (auto& r : result) { std::cout << r << ' '; } std::cout << std::endl; } int main() { show_lis(std::list { 3, 2, 6, 4, 5, 1 }); show_lis(std::vector { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }); }