📜  最长子序列差异最大为 K

📅  最后修改于: 2021-09-17 07:17:50             🧑  作者: Mango

给定一个长度为N的字符串S和一个整数K ,任务是找到最长子序列的长度,使得子序列中相邻字符的 ASCII 值之间的差异不超过 K。

例子:

Input: N = 7, K = 2, S = "afcbedg"
Output: 4
Explanation:
Longest special sequence present 
in "afcbedg" is a, c, b, d.
It is special because |a - c| <= 2, 
|c - b| <= 2 and | b-d| <= 2

Input: N = 13, K = 3, S = "geeksforgeeks"
Output: 7

朴素的方法:暴力解决方案是生成各种长度的所有可能子序列并计算有效子序列的最大长度。时间复杂度将是指数级的。

高效的方法:一种有效的方法是使用动态规划的概念

  • 创建一个大小等于字符串长度的 0 数组dp
  • 创建一个支持数组max_length,其中 0 的大小为 26。
  • 迭代由字符和用于每个字符的字符串的字符确定上限和下限。
  • 在上下限范围内迭代嵌套循环。
  • 用当前dp索引和当前 max_length 索引+1 之间的最大值填充 dp 数组。
  • 用当前dp索引和当前 max_length 索引之间的最大值填充 max_length 数组。
  • 最长子序列长度是dp数组中的最大值。
  • 让我们考虑一个例子:

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find
// the longest Special Sequence
int longest_subseq(int n, int k, string s)
{
 
    // Creating a list with
    // all 0's of size
    // equal to the length of string
    vector dp(n, 0);
 
    // Supporting list with
    // all 0's of size 26 since
    // the given string consists
    // of only lower case alphabets
    int max_length[26] = {0};
 
    for (int i = 0; i < n; i++)
    {
 
        // Converting the ascii value to
        // list indices
        int curr = s[i] - 'a';
         
        // Determining the lower bound
        int lower = max(0, curr - k);
         
        // Determining the upper bound
        int upper = min(25, curr + k);
         
        // Filling the dp array with values
        for (int j = lower; j < upper + 1; j++)
        {
            dp[i] = max(dp[i], max_length[j] + 1);
        }
        //Filling the max_length array with max
        //length of subsequence till now
        max_length[curr] = max(dp[i], max_length[curr]);
    }
 
    int ans = 0;
 
    for(int i:dp) ans = max(i, ans);
 
    // return the max length of subsequence
    return ans;
}
 
// Driver Code
int main()
{
    string s = "geeksforgeeks";
    int n = s.size();
    int k = 3;
    cout << (longest_subseq(n, k, s));
    return 0;
}
 
// This code is contributed by Mohit Kumar


Java
// Java program for the above approach
class GFG
{
 
// Function to find
// the longest Special Sequence
static int longest_subseq(int n, int k, String s)
{
 
    // Creating a list with
    // all 0's of size
    // equal to the length of String
    int []dp = new int[n];
 
    // Supporting list with
    // all 0's of size 26 since
    // the given String consists
    // of only lower case alphabets
    int []max_length = new int[26];
 
    for (int i = 0; i < n; i++)
    {
 
        // Converting the ascii value to
        // list indices
        int curr = s.charAt(i) - 'a';
         
        // Determining the lower bound
        int lower = Math.max(0, curr - k);
         
        // Determining the upper bound
        int upper = Math.min(25, curr + k);
         
        // Filling the dp array with values
        for (int j = lower; j < upper + 1; j++)
        {
            dp[i] = Math.max(dp[i], max_length[j] + 1);
        }
         
        // Filling the max_length array with max
        // length of subsequence till now
        max_length[curr] = Math.max(dp[i], max_length[curr]);
    }
 
    int ans = 0;
 
    for(int i:dp) ans = Math.max(i, ans);
 
    // return the max length of subsequence
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    String s = "geeksforgeeks";
    int n = s.length();
    int k = 3;
    System.out.print(longest_subseq(n, k, s));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Function to find
# the longest Special Sequence
def longest_subseq(n, k, s):
   
    # Creating a list with
    # all 0's of size
    # equal to the length of string
    dp = [0] * n
     
    # Supporting list with
    # all 0's of size 26 since
    # the given string consists
    # of only lower case alphabets
    max_length = [0] * 26
 
    for i in range(n):
 
        # Converting the ascii value to
        # list indices
        curr = ord(s[i]) - ord('a')
        # Determining the lower bound
        lower = max(0, curr - k)
        # Determining the upper bound
        upper = min(25, curr + k)
        # Filling the dp array with values
        for j in range(lower, upper + 1):
 
            dp[i] = max(dp[i], max_length[j]+1)
        # Filling the max_length array with max
        # length of subsequence till now
        max_length[curr] = max(dp[i], max_length[curr])
 
    # return the max length of subsequence
    return max(dp)
 
# driver code
def main():
  s = "geeksforgeeks"
  n = len(s)
  k = 3
  print(longest_subseq(n, k, s))
 
main()


C#
// C# program for the above approach
using System;
 
class GFG
{
 
// Function to find
// the longest Special Sequence
static int longest_subseq(int n, int k, String s)
{
 
    // Creating a list with
    // all 0's of size
    // equal to the length of String
    int []dp = new int[n];
 
    // Supporting list with
    // all 0's of size 26 since
    // the given String consists
    // of only lower case alphabets
    int []max_length = new int[26];
 
    for (int i = 0; i < n; i++)
    {
 
        // Converting the ascii value to
        // list indices
        int curr = s[i] - 'a';
         
        // Determining the lower bound
        int lower = Math.Max(0, curr - k);
         
        // Determining the upper bound
        int upper = Math.Min(25, curr + k);
         
        // Filling the dp array with values
        for (int j = lower; j < upper + 1; j++)
        {
            dp[i] = Math.Max(dp[i], max_length[j] + 1);
        }
         
        // Filling the max_length array with max
        // length of subsequence till now
        max_length[curr] = Math.Max(dp[i], max_length[curr]);
    }
 
    int ans = 0;
 
    foreach(int i in dp) ans = Math.Max(i, ans);
 
    // return the max length of subsequence
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
    String s = "geeksforgeeks";
    int n = s.Length;
    int k = 3;
    Console.Write(longest_subseq(n, k, s));
}
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:
7

时间复杂度: O(N)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程