diff --git a/src/algorithms/sets/longest-increasing-subsequence/dpLongestIncreasingSubsequence.js b/src/algorithms/sets/longest-increasing-subsequence/dpLongestIncreasingSubsequence.js index e5f2ec6dbf..6a76ffe9cb 100644 --- a/src/algorithms/sets/longest-increasing-subsequence/dpLongestIncreasingSubsequence.js +++ b/src/algorithms/sets/longest-increasing-subsequence/dpLongestIncreasingSubsequence.js @@ -5,49 +5,27 @@ * @param {number[]} sequence * @return {number} */ -export default function dpLongestIncreasingSubsequence(sequence) { - // Create array with longest increasing substrings length and - // fill it with 1-s that would mean that each element of the sequence - // is itself a minimum increasing subsequence. - const lengthsArray = Array(sequence.length).fill(1); +export default function longestIncreasingSubsequence(sequence) { + if (sequence.length === 0) return 0; - let previousElementIndex = 0; - let currentElementIndex = 1; + const tails = []; - while (currentElementIndex < sequence.length) { - if (sequence[previousElementIndex] < sequence[currentElementIndex]) { - // If current element is bigger then the previous one then - // current element is a part of increasing subsequence which - // length is by one bigger then the length of increasing subsequence - // for previous element. - const newLength = lengthsArray[previousElementIndex] + 1; - if (newLength > lengthsArray[currentElementIndex]) { - // Increase only if previous element would give us bigger subsequence length - // then we already have for current element. - lengthsArray[currentElementIndex] = newLength; + for (const num of sequence) { + let left = 0; + let right = tails.length; + + // Binary search + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (tails[mid] < num) { + left = mid + 1; + } else { + right = mid; } } - // Move previous element index right. - previousElementIndex += 1; - - // If previous element index equals to current element index then - // shift current element right and reset previous element index to zero. - if (previousElementIndex === currentElementIndex) { - currentElementIndex += 1; - previousElementIndex = 0; - } - } - - // Find the biggest element in lengthsArray. - // This number is the biggest length of increasing subsequence. - let longestIncreasingLength = 0; - - for (let i = 0; i < lengthsArray.length; i += 1) { - if (lengthsArray[i] > longestIncreasingLength) { - longestIncreasingLength = lengthsArray[i]; - } + tails[left] = num; } - return longestIncreasingLength; + return tails.length; }