基于贪心算法和二分搜索编写计算最长上升子序列的理解
时间: 2023-06-19 22:08:13 浏览: 109
计算最长上升子序列(Longest Increasing Subsequence,简称LIS)是一个经典的问题,可以用贪心算法和二分搜索来解决。
贪心算法的思想是,每次选择当前最优的解决方案,希望最终能够得到全局最优解。对于LIS问题,我们可以使用一个数组d来记录当前LIS的长度和最后一个元素的值。我们从左到右遍历数组,对于每个元素,我们可以将其插入到d数组中,有以下两种情况:
1.如果当前元素比d数组中最后一个元素还要大,我们可以直接将当前元素插入到d数组的末尾,并将LIS长度加1。
2.如果当前元素比d数组中最后一个元素小,我们可以使用二分搜索在d数组中找到第一个大于等于当前元素的位置,将该位置的值替换为当前元素。这样做的原因是,如果我们将d数组中的某个位置i替换为当前元素,那么以i结尾的LIS长度就会变成以当前元素结尾的LIS长度,而且这个新的LIS长度比原来的LIS长度更有可能变得更长。
最终,d数组的长度就是LIS的长度。
总的来说,贪心算法和二分搜索的结合能够高效地解决LIS问题,时间复杂度为O(nlogn)。
相关问题
对比基于动态规划编写计算最长上升子序列方法和基于贪心算法和二分搜索编写计算最长上升子序列方法在不同数据量下运行时间的差异
基于动态规划的算法是一种自底向上的算法,它需要计算所有可能的子问题,然后再根据子问题的解来计算原问题的解。因此,它的时间复杂度是 O(n^2)。
而基于贪心算法和二分搜索的算法则是一种自顶向下的算法。它维护一个长度为 i 的上升子序列的最小末尾值,对于每个新的元素,如果它比当前最小末尾值大,就将它加入到上升子序列中,否则就用二分搜索找到第一个大于等于它的元素,并将它替换为当前元素。该算法的时间复杂度是 O(nlogn)。
因此,在数据量较小的情况下,两种算法的运行时间差异不太明显,但是随着数据量的增加,基于动态规划的算法的运行时间将呈指数级增长,而基于贪心算法和二分搜索的算法的运行时间则仅呈对数级增长,因此它在处理大规模数据时表现更优。
基于贪心算法和二分搜索编写计算最长上升子序列方法的代码
以下是基于贪心算法和二分搜索的计算最长上升子序列的 Python3 代码:
```python
def lengthOfLIS(nums):
tails = [0] * len(nums)
size = 0
for x in nums:
i, j = 0, size
while i != j:
m = (i + j) // 2
if tails[m] < x:
i = m + 1
else:
j = m
tails[i] = x
size = max(i + 1, size)
return size
```
其中,`tails` 数组用于存储长度为 `i+1` 的上升子序列的末尾元素的最小值,`size` 记录当前最长上升子序列的长度。
我们遍历数组 `nums`,对于每个元素 `x`,在 `tails` 数组中查找第一个大于等于 `x` 的元素,使用二分搜索实现。如果找到了这样的元素,将其替换为 `x`,如果没有找到,将 `x` 加入到 `tails` 数组的末尾,此时最长上升子序列的长度加一。
最终返回 `size` 即可。
阅读全文