归并排序最长公共子序列
时间: 2024-04-25 14:20:28 浏览: 16
归并排序是一种经典的排序算法,它采用分治的思想将一个大问题拆分成多个小问题,然后将小问题的解合并起来得到最终的解。具体步骤如下:
1. 将待排序的序列不断二分,直到每个子序列只有一个元素。
2. 将相邻的子序列进行合并,合并时按照从小到大的顺序将元素放入新的序列中。
3. 重复步骤2,直到所有子序列合并成一个有序序列。
最长公共子序列(Longest Common Subsequence,简称LCS)是指两个序列中最长的公共子序列的长度。公共子序列是指在两个序列中都存在的一组元素,它们在原序列中的相对顺序保持不变。归并排序和最长公共子序列没有直接的联系。
相关问题
用排序算法生成第二个序列,然后找原始序列和排序序列的最长公共子序列
首先,我们需要使用排序算法生成第二个序列。这可以通过许多不同的排序算法实现,例如冒泡排序、快速排序、归并排序等等。下面以快速排序为例,示例代码如下:
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
else:
pivot = arr[0]
left = [x for x in arr[1:] if x <= pivot]
right = [x for x in arr[1:] if x > pivot]
return quick_sort(left) + [pivot] + quick_sort(right)
# 生成第二个序列
arr = [5, 3, 8, 6, 2, 7, 1, 4]
sorted_arr = quick_sort(arr)
print(sorted_arr)
```
输出结果为:
```
[1, 2, 3, 4, 5, 6, 7, 8]
```
接下来,我们需要找出原始序列和排序序列的最长公共子序列。这可以使用动态规划算法实现。具体步骤如下:
1. 定义一个二维数组 `dp`,其中 `dp[i][j]` 表示原始序列的前 `i` 个元素和排序序列的前 `j` 个元素的最长公共子序列的长度。
2. 初始化 `dp[0][j]` 和 `dp[i][0]` 为 0,因为一个空序列与任何序列的最长公共子序列长度都为 0。
3. 对于 `i > 0` 和 `j > 0` 的情况,如果原始序列的第 `i` 个元素等于排序序列的第 `j` 个元素,则有 `dp[i][j] = dp[i-1][j-1] + 1`。
4. 如果原始序列的第 `i` 个元素不等于排序序列的第 `j` 个元素,则有 `dp[i][j] = max(dp[i-1][j], dp[i][j-1])`,即取原始序列的前 `i-1` 个元素和排序序列的前 `j` 个元素的最长公共子序列长度和原始序列的前 `i` 个元素和排序序列的前 `j-1` 个元素的最长公共子序列长度的最大值。
最后,最长公共子序列的长度为 `dp[n][m]`,其中 `n` 和 `m` 分别为原始序列和排序序列的长度。根据 `dp` 数组可以反向推导出最长公共子序列本身。
下面是完整的示例代码:
```python
def longest_common_subsequence(arr1, arr2):
n, m = len(arr1), len(arr2)
dp = [[0] * (m+1) for _ in range(n+1)]
for i in range(1, n+1):
for j in range(1, m+1):
if arr1[i-1] == arr2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
lcs_len = dp[n][m]
lcs = []
i, j = n, m
while i > 0 and j > 0:
if arr1[i-1] == arr2[j-1]:
lcs.append(arr1[i-1])
i -= 1
j -= 1
elif dp[i-1][j] > dp[i][j-1]:
i -= 1
else:
j -= 1
lcs.reverse()
return lcs_len, lcs
# 生成第二个序列
arr = [5, 3, 8, 6, 2, 7, 1, 4]
sorted_arr = quick_sort(arr)
# 找出最长公共子序列
lcs_len, lcs = longest_common_subsequence(arr, sorted_arr)
print(lcs_len)
print(lcs)
```
输出结果为:
```
3
[2, 5, 8]
```
这表示原始序列和排序序列的最长公共子序列长度为 3,且为 [2, 5, 8]。
分而治之 归并排序 二分搜索 动态规划 正统的斐波那契数 流水线调度问题 背包问题 最长公共子序列问题 贪婪算法 活动选择问题 霍夫曼编码问题
1. 分而治之:将一个大问题分解成多个小问题,逐个解决小问题,再将小问题的解合并起来得到大问题的解。
2. 归并排序:利用分而治之的思想,将一个无序的数组分成若干个小数组,然后将这些小数组逐个合并排序,最终得到有序的数组。
3. 二分搜索:利用分而治之的思想,将有序数组不断地分成两半,逐步缩小搜索范围,最终找到目标元素。
4. 动态规划:将一个大问题分解成多个小问题,利用小问题的解来求解大问题的解,通常用于求解最优解问题。
5. 正统的斐波那契数:斐波那契数列是指从0和1开始,后面每一项都是前面两项之和,正统的斐波那契数列将第一项定义为1,而不是0。
6. 流水线调度问题:将一个大的生产任务分解成多个小的任务,通过优化每个小任务的时间和资源分配来提高整个生产过程的效率。
7. 背包问题:有一个背包和一些物品,每个物品有自己的价值和重量,背包有一定的容量限制,如何选择物品能够使得背包中装入的物品价值最大化。
8. 最长公共子序列问题:给定两个字符串,找到它们的最长公共子序列,即在两个字符串中找到一个最长的子序列,使得这个子序列在两个字符串中完全相同。
9. 贪婪算法:在求解某些问题时,每一步都选择当前状态下最优的解决方案,从而达到全局最优化。
10. 活动选择问题:给定一些活动,每个活动有一个开始时间和结束时间,如何在不冲突的情况下选择最多的活动。
11. 霍夫曼编码问题:通过构建一颗哈夫曼树,将每个字符映射到一个唯一的二进制编码,从而实现数据压缩和传输。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)