判断一个序列是否为另一个序列的子序列(两种算法)

这篇博客介绍了如何判断一个序列是否为另一个序列的子序列,提供了两种算法:一种时间复杂度为O(n^2),另一种为O(n)。通过遍历和比较两个序列的元素,实现子序列的判断。在C++中用模板函数实现,并在main函数中给出示例测试。
摘要由CSDN通过智能技术生成
/**
 判断Xm是否是Yn的子序列
 查找过程如下图所示:
 
 a[]: B   C   D   F      i下标   n
      |\  |\  |
 b[]: A B D C A D F E    j下标   m
 */

#include <iostream>

/**
 解一:时间复杂度为O(n^2) 
 设|a[n]|≤|b[m]|  
 */
template <class T>
bool IsSubSequence(T a[], int n, T b[], int m) {
    int t;
    t = 0;
    for (int i=0; i<n; i++) {
        
        for (int j=t;; j++) {
            
            if (a[i]==b[j]) {
                /**
                 找到,记住j位置,下一次从j+1开始.
                 */  
                t=j+1;
                break; 
            }
            
            if (j>=m)
            /**
             没有找到,所以不是子序列。 
             */
                return false;
        }
    }
    return true;
    /**
     全部比较完,都已经找到。
     */ 
}

/** 解二:时间复杂度为O(n) */
template <class T>
bool _IsSubSequence(T a[], int n, T b[], int m)
{
    int i=0;
    int j=0;
    while 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是四种常用方法一个序列的最大连续子序列的和: 1. 蛮力法:对于每一个子序列,计算它们的和,最后找出最大值。时间复杂度为 O(n^2)。 ```python def max_subarray_sum_brute_force(nums): n = len(nums) max_sum = float("-inf") for i in range(n): cur_sum = 0 for j in range(i, n): cur_sum += nums[j] max_sum = max(max_sum, cur_sum) return max_sum ``` 2. 分治法:将序列分成左右两部分,分别左部分、右部分和跨越中点的最大子序列和,最后将三个值取最大值。时间复杂度为 O(nlogn)。 ```python def max_subarray_sum_divide_conquer(nums): n = len(nums) def max_crossing_sum(nums, left, mid, right): left_max_sum = float("-inf") cur_sum = 0 for i in range(mid, left-1, -1): cur_sum += nums[i] left_max_sum = max(left_max_sum, cur_sum) right_max_sum = float("-inf") cur_sum = 0 for i in range(mid+1, right+1): cur_sum += nums[i] right_max_sum = max(right_max_sum, cur_sum) return left_max_sum + right_max_sum def max_subarray_sum(nums, left, right): if left == right: return nums[left] mid = (left + right) // 2 left_max_sum = max_subarray_sum(nums, left, mid) right_max_sum = max_subarray_sum(nums, mid+1, right) crossing_max_sum = max_crossing_sum(nums, left, mid, right) return max(left_max_sum, right_max_sum, crossing_max_sum) return max_subarray_sum(nums, 0, n-1) ``` 3. 动态规划法:定义一个变量 cur_sum,用来记录当前的连续子序列和,如果 cur_sum 小于等于 0,则从下一个元素重新开始计算,否则继续累加。用一个变量 max_sum 记录最大的连续子序列和。时间复杂度为 O(n)。 ```python def max_subarray_sum_dp(nums): n = len(nums) cur_sum = nums[0] max_sum = nums[0] for i in range(1, n): cur_sum = max(cur_sum + nums[i], nums[i]) max_sum = max(max_sum, cur_sum) return max_sum ``` 4. Kadane算法:与动态规划法类似,但只需要一个变量 cur_sum 来记录当前的连续子序列和,不需要用一个变量 max_sum 记录最大的连续子序列和,而是在每次更新 cur_sum 的时候,同时更新最大值。时间复杂度为 O(n)。 ```python def max_subarray_sum_kadane(nums): n = len(nums) cur_sum = nums[0] max_sum = nums[0] for i in range(1, n): cur_sum = max(nums[i], cur_sum + nums[i]) max_sum = max(max_sum, cur_sum) return max_sum ``` 这四种方法的时间复杂度分别为 O(n^2)、O(nlogn)、O(n) 和 O(n),其中 Kadane算法 是最优的。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值