0% completed
Given an integer array nums
, return the number of longest increasing subsequences.
A subsequence
is derived from the array by deleting
some or no elements without changing the order of the remaining elements
Note: Sequences should be strictly increasing.
Example 1:
[2, 6, 4, 3, 5]
2
[2, 3, 5]
and [2, 4, 5]
, both having a length of 3. Therefore, there are two such subsequences.Example 2:
[10, 9, 2, 5, 3, 7, 101, 18]
4
[2, 3, 7, 18]
, [2, 5, 7, 18]
, [2, 3, 101]
, and [2, 5, 101]
, each having a length of 4. Thus, there are four such subsequences.Example 3:
[1, 5, 2, 6, 3, 7]
3
[1, 2, 3, 7]
, [1, 2, 6, 7]
, and [1, 5, 6, 7]
.Constraints:
To solve this problem, the Binary Indexed Tree (BIT) algorithm is a great choice due to its efficiency in handling prefix sums and updates. The key idea is to maintain a frequency and length count for subsequences ending at each index of the array. Using BIT allows us to efficiently calculate and update the number of valid subsequences that can be extended by adding the current number.
This approach works because BIT efficiently tracks cumulative sums and updates in logarithmic time, which is crucial for handling the dynamic nature of the problem. Given that we need to frequently update and query subsequence lengths, BIT ensures that these operations are performed quickly, making it a suitable and effective approach for solving this problem.
Initialize Variables:
Nums
.Nums
to use in sorting.BITNode
objects (Binary Indexed Tree), each holding maxLength
and frequency
.Create and Sort Index List:
[0, 1, 2, ..., n-1]
corresponding to elements in nums
.Indices
based on values in nums
. If two elements are equal, prioritize the one with the higher index.
Process Each Element:
getMax(index)
to find the maximum length of the LIS that ends before the current index.maxLength == 0
, start a new subsequence by calling update(index, 1, 1)
.maxLength > 0
, find the frequency of subsequences with this length using getFrequency(index, maxLength)
.update(index, maxLength + 1, frequency)
to record a new subsequence with updated length and frequency.BIT Operations:
index + 1
and moves upwards through the BIT by subtracting the last set bit (index -= index & -index
).maxLength
stored at the current position in the BIT and updates the result with the maximum value found.getMax
, it starts at index + 1
and moves upwards through the BIT.maxLength
at the current position matches the target maxLength
. If it does, the corresponding frequency
is added to the result.maxLength
that ends before the specified index.index + 1
and moves downwards through the BIT by adding the last set bit (index += index & -index
).maxLength
at the current position:
maxLength
is less than the current maxLength
, it updates both maxLength
and frequency
.maxLength
is equal to the current maxLength
, it adds the frequency
to the existing value.Final Result:
getMax(n-1)
.getFrequency(n-1, maxLength)
.Input: nums = [2, 6, 4, 3, 5]
Initialization:
nums = [2, 6, 4, 3, 5]
n = 5
.bit
: A list of 6 BITNode
objects, each initialized with maxLength = 0
and frequency = 0
.Create and Sort Index List:
nums
).indices
using custom comparator cmp
, based on values in nums
:
[2, 3, 4, 5, 6]
.Process Each Element:
Index 0 (nums[0] = 2
):
getMax(0)
):
index + 1
).maxLength = 0
.maxLength == 0
, start a new subsequence:update(0, 1, 1)
):
[0, (1,1), (1,1), (0,0), (1,1), (0,0)]
.Index 3 (nums[3] = 3
):
getMax(3)
):
index + 1
).maxLength = 1
.getFrequency(3, 1)
):
frequency = 1
.update(3, 2, 1)
):
[0, (1,1), (1,1), (0,0), (2,1), (0,0)]
.Index 2 (nums[2] = 4
):
getMax(2)
):
index + 1
).maxLength = 1
.getFrequency(2, 1)
):
frequency = 1
.update(2, 2, 1)
):
[0, (1,1), (1,1), (2,1), (2,2), (0,0)]
.Index 4 (nums[4] = 5
):
getMax(4)
):
index + 1
).maxLength = 2
.getFrequency(4, 2)
):
frequency = 2
.update(4, 3, 2)
):
[0, (1,1), (1,1), (2,1), (2,2), (3,2)]
.Index 1 (nums[1] = 6
):
getMax(1)
):
index + 1
).maxLength = 1
.getFrequency(1, 1)
):
frequency = 1
.update(1, 4, 2)
):
[0, (1,1), (2,1), (2,1), (2,3), (3,2)]
.Final Result:
getMax(4)
):
index + 1
).maxLength = 3
.getFrequency(4, 3)
):
frequency = 2
.2
as the number of longest increasing subsequences......
.....
.....