📜  给定总和 K 的最长公共子序列的长度

📅  最后修改于: 2022-05-13 01:56:04.501000             🧑  作者: Mango

给定总和 K 的最长公共子序列的长度

给定两个数组a[]b[]以及一个整数K ,任务是找到最长公共子序列的长度,使得元素之和等于K

例子:

方法:解决方案的方法基于最长公共子序列的概念,我们需要检查子序列的元素之和是否等于给定值。请按照以下步骤操作;

  • 考虑变量sum初始化为给定值。
  • 每次当元素包含在子序列中时,减少该元素的总和值。
  • 在基本条件中检查总和值是否为 0,这意味着该子序列的总和等于K。因此当sum为零时返回 0,否则返回 INT_MIN

以下是上述方法的实现:

C++
// C++ code to implement the approach
#include 
using namespace std;
int solve(int a[], int b[], int i, int j, int sum)
{
    if (sum == 0)
        return 0;
    if (sum < 0)
        return INT_MIN;
 
    if (i == 0 || j == 0) {
        if (sum == 0)
            return 0;
        else
            return INT_MIN;
    }
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1])
        return max(
            1 + solve(a, b, i - 1, j - 1, sum - a[i - 1]),
            solve(a, b, i - 1, j - 1, sum));
 
    return max(solve(a, b, i - 1, j, sum),
               solve(a, b, i, j - 1, sum));
}
 
// Driver code
int main()
{
    int a[] = { 9, 11, 2, 1, 6, 2, 7 };
    int b[] = { 1, 2, 6, 9, 2, 3, 11, 7 };
    int n = sizeof(a) / sizeof(int);
    int m = sizeof(b) / sizeof(int);
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum);
    if (ans >= 0)
        cout << ans << endl;
    else
        cout << -1;
    return 0;
}


Java
// Java code to implement the approach
import java.io.*;
class GFG {
 
  static int solve(int a[], int b[], int i, int j, int sum)
  {
    if (sum == 0)
      return 0;
    if (sum < 0)
      return Integer.MIN_VALUE;
 
    if (i == 0 || j == 0) {
      if (sum == 0)
        return 0;
      else
        return Integer.MIN_VALUE;
    }
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1])
      return Math.max(
      1 + solve(a, b, i - 1, j - 1, sum - a[i - 1]),
      solve(a, b, i - 1, j - 1, sum));
 
    return Math.max(solve(a, b, i - 1, j, sum),
                    solve(a, b, i, j - 1, sum));
  }
 
  // Driver code
  public static void main (String[] args) {
    int a[] = { 9, 11, 2, 1, 6, 2, 7 };
    int b[] = { 1, 2, 6, 9, 2, 3, 11, 7 };
    int n = a.length;
    int m = b.length;
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum);
    if (ans >= 0)
      System.out.print(ans);
    else
      System.out.print(-1);
  }
}
 
// This code is contributed by hrithikgarg03188.


Python3
# Python code for the above approach
def solve(a, b,  i,  j,  sum):
 
    if sum == 0:
        return 0
    if sum < 0:
        return -2147483648
 
    if i == 0 or j == 0:
        if sum == 0:
            return 0
        else:
            return -2147483648
 
    # If values are same then we can include this
    # or also can't include this
    if (a[i - 1] == b[j - 1]):
        return max(
            1 + solve(a, b, i - 1, j - 1, sum - a[i - 1]),
            solve(a, b, i - 1, j - 1, sum))
 
    return max(solve(a, b, i - 1, j, sum),
               solve(a, b, i, j - 1, sum))
 
# Driver code
a = [9, 11, 2, 1, 6, 2, 7]
b = [1, 2, 6, 9, 2, 3, 11, 7]
n = len(a)
m = len(b)
sum = 18
 
ans = solve(a, b, n, m, sum)
if (ans >= 0):
    print(ans)
else:
    print(-1)
 
# This code is contributed by Potta Lokesh


C#
// C# code to implement the approach
using System;
class GFG {
 
  static int solve(int[] a, int[] b, int i, int j,
                   int sum)
  {
    if (sum == 0)
      return 0;
    if (sum < 0)
      return Int32.MinValue;
 
    if (i == 0 || j == 0) {
      if (sum == 0)
        return 0;
      else
        return Int32.MinValue;
    }
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1])
      return Math.Max(1
                      + solve(a, b, i - 1, j - 1,
                              sum - a[i - 1]),
                      solve(a, b, i - 1, j - 1, sum));
 
    return Math.Max(solve(a, b, i - 1, j, sum),
                    solve(a, b, i, j - 1, sum));
  }
 
  // Driver code
  public static void Main()
  {
    int[] a = { 9, 11, 2, 1, 6, 2, 7 };
    int[] b = { 1, 2, 6, 9, 2, 3, 11, 7 };
    int n = a.Length;
    int m = b.Length;
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum);
    if (ans >= 0)
      Console.Write(ans);
    else
      Console.Write(-1);
  }
}
 
// This code is contributed by Samim Hossain Mondal..


Javascript


C++
// C++ code to implement the approach
#include 
using namespace std;
 
// Function to find longest common subsequence having sum
// equal to given value
int solve(int a[], int b[], int i, int j, int sum,
          map& mp)
{
    if (sum == 0)
        return 0;
 
    if (sum < 0)
        return INT_MIN;
 
    if (i == 0 || j == 0) {
        if (sum == 0)
            return 0;
        else
            return INT_MIN;
    }
 
    string temp = to_string(i) + '#'
                  + to_string(j) + '#'
                  + to_string(sum);
    if (mp.find(temp) != mp.end())
        return mp[temp];
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1])
        return mp[temp]
               = max(
                   1 + solve(a, b, i - 1, j - 1,
                             sum - a[i - 1], mp),
                   solve(a, b, i - 1, j - 1, sum, mp));
 
    return mp[temp]
           = max(solve(a, b, i - 1, j, sum, mp),
                 solve(a, b, i, j - 1, sum, mp));
}
 
// Driver code
int main()
{
    int a[] = { 9, 11, 2, 1, 6, 2, 7 };
    int b[] = { 1, 2, 6, 9, 2, 3, 11, 7 };
    map mp;
    int n = sizeof(a) / sizeof(int);
    int m = sizeof(b) / sizeof(int);
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum, mp);
    if (ans >= 0)
        cout << ans << endl;
    else
        cout << -1;
    return 0;
}


Java
// Java code to implement the approach
import java.util.*;
 
class GFG{
 
  // Function to find longest common subsequence having sum
  // equal to given value
  static int solve(int a[], int b[], int i, int j, int sum,
                   HashMap mp)
  {
    if (sum == 0)
      return 0;
 
    if (sum < 0)
      return Integer.MIN_VALUE;
 
    if (i == 0 || j == 0) {
      if (sum == 0)
        return 0;
      else
        return Integer.MIN_VALUE;
    }
 
    String temp = String.valueOf(i) + '#'
      + String.valueOf(j) + '#'
      + String.valueOf(sum);
    if (mp.containsKey(temp))
      return mp.get(temp);
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1]) {
      mp.put(temp, Math.max(
        1 + solve(a, b, i - 1, j - 1,
                  sum - a[i - 1], mp),
        solve(a, b, i - 1, j - 1, sum, mp)));
      return mp.get(temp);
    }
 
    mp.put(temp,  Math.max(solve(a, b, i - 1, j, sum, mp),
                           solve(a, b, i, j - 1, sum, mp)));
    return mp.get(temp);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int a[] = { 9, 11, 2, 1, 6, 2, 7 };
    int b[] = { 1, 2, 6, 9, 2, 3, 11, 7 };
    HashMap mp = new HashMap<>();
    int n = a.length;
    int m = b.length;
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum, mp);
    if (ans >= 0)
      System.out.print(ans +"\n");
    else
      System.out.print(-1);
  }
}
 
// This code is contributed by shikhasingrajput


C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
class GFG {
 
  // Function to find longest common subsequence having
  // sum equal to given value
  static int solve(int[] a, int[] b, int i, int j,
                   int sum, Dictionary mp)
  {
    if (sum == 0)
      return 0;
 
    if (sum < 0)
      return Int32.MinValue;
 
    if (i == 0 || j == 0) {
      if (sum == 0)
        return 0;
      else
        return Int32.MinValue;
    }
 
    string temp = i.ToString() + "#" + j.ToString()
      + "#" + sum.ToString();
    if (mp.ContainsKey(temp))
      return mp[temp];
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1])
      return mp[temp] = Math.Max(
      1
      + solve(a, b, i - 1, j - 1,
              sum - a[i - 1], mp),
      solve(a, b, i - 1, j - 1, sum, mp));
 
    return mp[temp]
      = Math.Max(solve(a, b, i - 1, j, sum, mp),
                 solve(a, b, i, j - 1, sum, mp));
  }
 
  // Driver code
  public static void Main()
  {
    int[] a = { 9, 11, 2, 1, 6, 2, 7 };
    int[] b = { 1, 2, 6, 9, 2, 3, 11, 7 };
    Dictionary mp
      = new Dictionary();
 
    int n = a.Length;
    int m = b.Length;
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum, mp);
    if (ans >= 0)
      Console.WriteLine(ans);
    else
      Console.Write(-1);
  }
}
 
// This code is contributed by Samim Hossain Mondal.



输出
3

时间复杂度: O(2 N ),两个数组中的 N 最大大小
辅助空间: O(1)

有效的方法:一种有效的方法是使用记忆来降低时间复杂度,其中每个状态存储具有和的子序列的最大长度。使用地图来实现这一点。

下面是上述方法的实现。

C++

// C++ code to implement the approach
#include 
using namespace std;
 
// Function to find longest common subsequence having sum
// equal to given value
int solve(int a[], int b[], int i, int j, int sum,
          map& mp)
{
    if (sum == 0)
        return 0;
 
    if (sum < 0)
        return INT_MIN;
 
    if (i == 0 || j == 0) {
        if (sum == 0)
            return 0;
        else
            return INT_MIN;
    }
 
    string temp = to_string(i) + '#'
                  + to_string(j) + '#'
                  + to_string(sum);
    if (mp.find(temp) != mp.end())
        return mp[temp];
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1])
        return mp[temp]
               = max(
                   1 + solve(a, b, i - 1, j - 1,
                             sum - a[i - 1], mp),
                   solve(a, b, i - 1, j - 1, sum, mp));
 
    return mp[temp]
           = max(solve(a, b, i - 1, j, sum, mp),
                 solve(a, b, i, j - 1, sum, mp));
}
 
// Driver code
int main()
{
    int a[] = { 9, 11, 2, 1, 6, 2, 7 };
    int b[] = { 1, 2, 6, 9, 2, 3, 11, 7 };
    map mp;
    int n = sizeof(a) / sizeof(int);
    int m = sizeof(b) / sizeof(int);
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum, mp);
    if (ans >= 0)
        cout << ans << endl;
    else
        cout << -1;
    return 0;
}

Java

// Java code to implement the approach
import java.util.*;
 
class GFG{
 
  // Function to find longest common subsequence having sum
  // equal to given value
  static int solve(int a[], int b[], int i, int j, int sum,
                   HashMap mp)
  {
    if (sum == 0)
      return 0;
 
    if (sum < 0)
      return Integer.MIN_VALUE;
 
    if (i == 0 || j == 0) {
      if (sum == 0)
        return 0;
      else
        return Integer.MIN_VALUE;
    }
 
    String temp = String.valueOf(i) + '#'
      + String.valueOf(j) + '#'
      + String.valueOf(sum);
    if (mp.containsKey(temp))
      return mp.get(temp);
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1]) {
      mp.put(temp, Math.max(
        1 + solve(a, b, i - 1, j - 1,
                  sum - a[i - 1], mp),
        solve(a, b, i - 1, j - 1, sum, mp)));
      return mp.get(temp);
    }
 
    mp.put(temp,  Math.max(solve(a, b, i - 1, j, sum, mp),
                           solve(a, b, i, j - 1, sum, mp)));
    return mp.get(temp);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int a[] = { 9, 11, 2, 1, 6, 2, 7 };
    int b[] = { 1, 2, 6, 9, 2, 3, 11, 7 };
    HashMap mp = new HashMap<>();
    int n = a.length;
    int m = b.length;
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum, mp);
    if (ans >= 0)
      System.out.print(ans +"\n");
    else
      System.out.print(-1);
  }
}
 
// This code is contributed by shikhasingrajput

C#

// C# code to implement the approach
using System;
using System.Collections.Generic;
class GFG {
 
  // Function to find longest common subsequence having
  // sum equal to given value
  static int solve(int[] a, int[] b, int i, int j,
                   int sum, Dictionary mp)
  {
    if (sum == 0)
      return 0;
 
    if (sum < 0)
      return Int32.MinValue;
 
    if (i == 0 || j == 0) {
      if (sum == 0)
        return 0;
      else
        return Int32.MinValue;
    }
 
    string temp = i.ToString() + "#" + j.ToString()
      + "#" + sum.ToString();
    if (mp.ContainsKey(temp))
      return mp[temp];
 
    // If values are same then we can include this
    // or also can't include this
    if (a[i - 1] == b[j - 1])
      return mp[temp] = Math.Max(
      1
      + solve(a, b, i - 1, j - 1,
              sum - a[i - 1], mp),
      solve(a, b, i - 1, j - 1, sum, mp));
 
    return mp[temp]
      = Math.Max(solve(a, b, i - 1, j, sum, mp),
                 solve(a, b, i, j - 1, sum, mp));
  }
 
  // Driver code
  public static void Main()
  {
    int[] a = { 9, 11, 2, 1, 6, 2, 7 };
    int[] b = { 1, 2, 6, 9, 2, 3, 11, 7 };
    Dictionary mp
      = new Dictionary();
 
    int n = a.Length;
    int m = b.Length;
    int sum = 18;
 
    int ans = solve(a, b, n, m, sum, mp);
    if (ans >= 0)
      Console.WriteLine(ans);
    else
      Console.Write(-1);
  }
}
 
// This code is contributed by Samim Hossain Mondal.


输出
3

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