This is a problem that could be done with some type of brute-force algorithm, but I was wondering if there are some efficient ways of doing this.
Let\'s assume that
Edit: As my misunderstanding, the previous approach is not correct.
Here is my second attempt:
If we view each number in a pair as node in a graph, we can build a bipartite graph, with edges between each node if there is a pair containing these two nodes.
So, this problem is reduced to find the maximum bipartite matching, which can be solved using classic Ford-fulkerson algorithm.
First wrong approach:
We can solve this by using dynamic programming.
Sorting the pair by their starting point, (if draw, by their ending point).
Assume that we have a function f
, with f(i)
returns the maximum number of pairs, if we choose from pair i
onward.
If we select a pair i
, we need to check what is the next smallest index greater than i
that is not overlapping with i
.
We have
f(i) = max(1 + f(next index not overlap i), f (i + 1))
Storing the result of f(i)
in a table, we can have a solution with O(n^2) time complexity, and the result will be f(0)
.
Pseudo code:
sort data;//Assume we have a data array to store all pairs
int[] dp;
int f(int index){
if(index == data.length)
return 0;
if(we have calculated this before)
return dp[index];
int nxt = -1;
for(int i = index + 1; i < data.length; i++){
if(data[i].start > data[index].end){
nxt = i;
break;
}
}
if(nxt == -1)
return dp[index] = max(1, f(index + 1));
return dp[index] = max(1 + f(nxt) , f(index + 1));
}