# Longest Increasing Subsequence

**1. Clarify the problem:**
Before diving into solving the problem, let's clarify the requirements:

- We are given an array of integers.
- Our task is to find the length of the longest increasing subsequence (LIS) in the array.
- A subsequence is a sequence of elements from the array, not necessarily contiguous, in which the elements are in increasing order.

**2. Analyze the problem:**
To solve this problem, we can use a dynamic programming approach to find the length of the LIS.

- We can iterate through the array and keep track of the LIS ending at each position.
- For each element, we check the elements before it to find the longest increasing subsequence that ends at the current element.
- We update the LIS ending at the current element based on the maximum LIS ending at the previous elements.

**3. Design an algorithm:**
Here is the algorithm to solve the problem:

- Initialize an array
`dp`

of the same length as the input array, with all elements set to 1. This array will store the length of the LIS ending at each position. - Iterate through the array from the second element to the end.
- For each element, iterate through all the previous elements.
- If the current element is greater than the previous element, update
`dp[i]`

as`max(dp[i], dp[j] + 1)`

where`j`

is the index of the previous element.

- Find the maximum value in the
`dp`

array and return it as the length of the longest increasing subsequence.

**4. Explain your approach:**
The approach involves using dynamic programming to find the length of the longest increasing subsequence (LIS) in the given array. We iterate through the array and keep track of the LIS ending at each position. For each element, we check the elements before it to find the longest increasing subsequence that ends at the current element. We update the LIS ending at the current element based on the maximum LIS ending at the previous elements. Finally, we find the maximum value in the `dp`

array, which represents the length of the LIS.

**5. Write clean and readable code:**

python

```
def lengthOfLIS(nums):
n = len(nums)
dp = [1] * n
for i in range(1, n):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
```

**6. Test your code:**
Let's test the code with different test cases:

`nums = [10, 9, 2, 5, 3, 7, 101, 18]`

- Expected output:
`4`

- Explanation: The longest increasing subsequence is
`[2, 3, 7, 101]`

with a length of 4.

- Expected output:
`nums = [0, 1, 0, 3, 2, 3]`

- Expected output:
`4`

- Explanation: The longest increasing subsequence is
`[0, 1, 2, 3]`

with a length of 4.

- Expected output:
`nums = [7, 7, 7, 7, 7, 7, 7]`

- Expected output:
`1`

- Explanation: Each individual element is a valid subsequence, and the longest increasing subsequence has a length of 1.

- Expected output:

**7. Optimize if necessary:**
The initial solution already follows an optimal approach using dynamic programming, so there is no further optimization required.

**8. Handle error cases:**
The code assumes that the input `nums`

is a valid list of integers. If the input is empty, the code will still work correctly and return 0, as there are no elements in the array to form a subsequence.

**9. Discuss complexity analysis:**

- The time complexity of the solution is O(n^2), where n is the length of the input array. This is because we have nested loops iterating through the array.
- The space complexity is O(n) since we use an additional array
`dp`

of length n to store the length of the LIS ending at each position. - The solution has an optimal time and space complexity given the problem requirements.