All O(N^2) solutions that I have seen for the longest increasing subsequence problem, as their first step, state something like this "Let L[i] be the length of the LIS ending at index i...":
And, while this is a working assumption (the one that helps us solve the problem), I'm more curious on why one shall assume that and pick this approach? Or, in other words, how does one's thought process evolve and end up with an idea that an array must be introduced where each element is a length of a subsequence that ends at i -- here, I'm questioning exactly, why L[i] shall reflect a subsequence ending at i (i.e. why not starting at i)?
To better illustrate my question: when I was trying to solve the problem myself, without knowing the solution available on the Internet, I came to similar realizations: the first one is that a) I need an array L and the second one that b) L[i] will determine the length of a subsequence starting at i (!). I then proceeded with implementing the solution which turned out to be working (see below). The solution is equivalent to the most popular one, though this core assumption is directly opposite. When I read the popular solution, I began wondering, why didn't I think of this (i.e. L[i] -- length of a subsequence ending at i)? The answer might be just random -- i.e. "why not?", but maybe there's something else to it?
While backtracking my own thought process, I realized it was just a straightforward way to think for me when I was looking at an example sequence and tried to "mentally" solve the problem -- i.e. build subsequences as I go from 0 to N. Does it just mean that for someone (or the majority) the straightforward way was to think of how (or where) the subsequence ends?
int lengthOfLIS(vector<int>& sequence) {
if (sequence.size() == 1) return 1;
if (sequence.size() == 0) return 0;
int maxLen = 1;
vector<int> LIS(sequence.size(), 1); // LIS[i] -- len of subseq starting at i
for (int i = sequence.size()-2; i >= 0; --i)
for (int j = i+1; j < sequence.size(); ++j)
if (sequence[i] < sequence[j])
{
LIS[i] = max(1+LIS[j], LIS[i]);
if (LIS[i] > maxLen) maxLen = LIS[i];
}
return maxLen;
}