Skip to content

Commit 6d72b63

Browse files
committed
update LIS and patience sort
1 parent f7a203e commit 6d72b63

4 files changed

+66
-59
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ A collection of commonly used algorithms, written in C/C++, java, Python...
1313
- Search
1414
- [K_{th} element selection](https://github.com/wandering007/algorithms/blob/master/kth_element_selection.cpp)
1515
- [Knuth–Morris–Pratt algorithm](https://github.com/wandering007/algorithms/blob/master/kmp.cpp)
16+
- [Longest increasing subsequence](https://github.com/wandering007/algorithms/blob/master/longest_increasing_subsequence.py)
1617
- Sorting
1718
- [Heap sort](https://github.com/wandering007/algorithms/blob/master/sorting/heap_sort.cpp)
19+
- [Patience sort](https://github.com/wandering007/algorithms/blob/master/sorting/patience_sort.cpp)
1820
- Computational Geometry
1921
- [Convex hull](https://github.com/wandering007/algorithms/blob/master/convex_hull.cpp)
2022
- Number Theory

Longest_increasing_subsequence.py longest_increasing_subsequence.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ def longest_increasing_subsequence(X):
88
M = [0] * (N + 1)
99
L = 0
1010
for i in range(N):
11-
# Binary search for the largest positive j <= L
11+
# Binary search for the largest positive j <= L
1212
lo = 1
1313
hi = L
1414
while lo <= hi:
15-
mid = (lo + hi) // 2
16-
if X[ M[mid] ] < X[i]:
15+
mid = (lo + hi + 1) // 2
16+
if X[M[mid]] < X[i]:
1717
lo = mid + 1
1818
else:
1919
hi = mid - 1
@@ -33,4 +33,4 @@ def longest_increasing_subsequence(X):
3333
for i in range(L - 1, -1, -1):
3434
S.append(X[k])
3535
k = P[k]
36-
return S[::-1]
36+
return S[::-1]

sorting/Patience_sort.cpp

-55
This file was deleted.

sorting/patience_sort.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <algorithm>
2+
#include <cassert>
3+
#include <iostream>
4+
#include <iterator>
5+
#include <stack>
6+
#include <vector>
7+
// reference:
8+
// https://rosettacode.org/wiki/Sorting_algorithms/Patience_sort#C.2B.2B
9+
template <class E>
10+
struct pile_less {
11+
bool operator()(const std::stack<E> &pile1,
12+
const std::stack<E> &pile2) const {
13+
return pile1.top() < pile2.top();
14+
}
15+
};
16+
17+
template <class E>
18+
struct pile_greater {
19+
bool operator()(const std::stack<E> &pile1,
20+
const std::stack<E> &pile2) const {
21+
return pile1.top() > pile2.top();
22+
}
23+
};
24+
25+
template <class Iterator>
26+
void patienceSort(Iterator first, Iterator last) {
27+
typedef typename std::iterator_traits<Iterator>::value_type E;
28+
typedef std::stack<E> Pile;
29+
30+
std::vector<Pile> piles;
31+
// sort into piles
32+
for (Iterator it = first; it != last; ++it) {
33+
E &x = *it;
34+
Pile newPile;
35+
newPile.push(x);
36+
typename std::vector<Pile>::iterator i = std::lower_bound(
37+
piles.begin(), piles.end(), newPile, pile_less<E>());
38+
if (i != piles.end())
39+
i->push(x);
40+
else
41+
piles.push_back(newPile);
42+
}
43+
44+
// priority queue allows us to merge piles efficiently
45+
// we use greater-than comparator for min-heap
46+
std::make_heap(piles.begin(), piles.end(), pile_greater<E>());
47+
for (Iterator it = first; it != last; ++it) {
48+
// moves the smallest to the end
49+
std::pop_heap(piles.begin(), piles.end(), pile_greater<E>());
50+
Pile &smallPile = piles.back();
51+
*it = smallPile.top();
52+
smallPile.pop();
53+
if (smallPile.empty())
54+
piles.pop_back();
55+
else
56+
// Inserts the element at the position end-1 into the min heap
57+
std::push_heap(piles.begin(), piles.end(), pile_greater<E>());
58+
}
59+
assert(piles.empty());
60+
}

0 commit comments

Comments
 (0)