Almost Sorted Array(最长上升子序列o(nlogn))

We are all familiar with sorting algorithms: quick sort, merge sort, heap sort, insertion sort, selection sort, bubble sort, etc. But sometimes it is an overkill to use these algorithms for an almost sorted array.
We say an array is sorted if its elements are in non-decreasing order or non-increasing order. We say an array is almost sorted if we can remove exactly one element from it, and the remaining array is sorted. Now you are given an array a1,a2,…,an, is it almost sorted?
Input
The first line contains an integer T indicating the total number of test cases. Each test case starts with an integer n in one line, then one line with n integers a1,a2,…,an.
1≤T≤2000
2≤n≤105
1≤ai≤105
There are at most 20 test cases with n>1000.
Output
For each test case, please output “YES” if it is almost sorted. Otherwise, output “NO” (both without quotes).
Sample Input
3
3
2 1 7
3
3 2 1
5
3 1 4 1 5
Sample Output
YES
YES
NO

动态规划思想:
状态转移方程为:f[i]=max(f[i],f[j+1]);
为了降低时间复杂度,要用到了二分查找

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,我们需要使用排序算法生成第二个序列。这可以通过许多不同的排序算法实现,例如冒泡排序、快速排序、归并排序等等。下面以快速排序为例,示例代码如下: ```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]。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Prime me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值