📌  相关文章
📜  通过删除由单个不同字符组成的子字符串可能获得的最大分数

📅  最后修改于: 2021-04-17 18:03:59             🧑  作者: Mango

给定一个二进制字符串S和数组A [],两者的大小N,任务是找到最大通过去除任何长度的子串得分可能,说K,由相同的字符,并加入A [K]的分数。

例子:

天真的方法:解决此问题的最简单的想法是使用递归。遍历字符串的字符。如果遇到仅由一个不同字符组成的子字符串,则继续进行搜索或删除子字符串,然后递归调用剩余字符串的函数。

下面是上述方法的实现:

Java
// Java program for the above approach
import java.util.*;
class GFG
{
   
  // Function to check if the string s consists
  // of a single distinct character or not
  static boolean isUnique(String s)
  {
    HashSet set = new HashSet<>();
    for (char c : s.toCharArray())
      set.add(c);
    return set.size() == 1;
  }
 
  // Function to calculate the maximum
  // score possible by removing substrings
  static int maxScore(String s, int[] a)
  {
    int n = s.length();
 
    // If string is empty
    if (n == 0)
      return 0;
 
    // If length of string is 1
    if (n == 1)
      return a[0];
 
    // Store the maximum result
    int mx = -1;
     
    // Try to remove all substrings that
    // satisfy the condition and check
    // for resultant string after removal
    for (int i = 0; i < n; i++)
    {
      for (int j = i; j < n; j++)
      {
 
        // Store the substring {s[i], .., s[j]}
        String sub = s.substring(i, j + 1);
 
        // Check if the substring contains
        // only a single distinct character
        if (isUnique(sub))
          mx = Math.max(
          mx,
          a[sub.length() - 1]
          + maxScore(
            s.substring(0, i)
            + s.substring(j + 1),
            a));
      }
    }
     
    // Return the maximum score
    return mx;
  }
   
  // Driver Code
  public static void main(String args[])
  {
    String s = "011";
    int a[] = { 1, 3, 1 };
    System.out.print(maxScore(s, a));
  }
}
 
// This code is contributed by hemanth gadarla.


Python3
# Python program for the above approach
 
# Function to check if the string s consists
# of a single distinct character or not
def isUnique(s):
    return True if len(set(s)) == 1 else False
 
# Function to calculate the maximum
# score possible by removing substrings
def maxScore(s, a):
    n = len(s)
 
    # If string is empty
    if n == 0:
        return 0
 
    # If length of string is 1
    if n == 1:
        return a[0]
 
    # Store the maximum result
    mx = -1
 
    # Try to remove all substrings that
    # satisfy the condition and check
    # for resultant string after removal
    for i in range(n):
        for j in range(i, n):
 
            # Store the substring {s[i], .., s[j]}
            sub = s[i:j + 1]
 
            # Check if the substring contains
            # only a single distinct character
            if isUnique(sub):
                mx = max(mx, a[len(sub)-1]
                         + maxScore(s[:i]+s[j + 1:], a))
 
        # Return the maximum score
    return mx
 
 
# Driver Code
if __name__ == "__main__":
 
    s = "011"
    a = [1, 3, 1]
    print(maxScore(s, a))


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Initialize a dictionary to
// store the precomputed results
map dp;
 
// Function to calculate the maximum
// score possible by removing substrings
int maxScore(string s, vector a)
{
 
  // If s is present in dp[] array
  if (dp.find(s) != dp.end())
    return dp[s];
 
  // Base Cases:
  int n = s.size();
 
  // If length of string is 0
  if (n == 0)
    return 0;
 
  // If length of string is 1
  if (n == 1)
    return a[0];
 
  // Put head pointer at start
  int head = 0;
 
  // Initialize the max variable
  int mx = -1;
 
  // Generate the substrings
  // using two pointers
  while (head < n)
  {
    int tail = head;
    while (tail < n)
    {
 
      // If s[head] and s[tail]
      // are different
      if (s[tail] != s[head])
      {
 
        // Move head to
        // tail and break
        head = tail;
        break;
      }
 
      // Store the substring
      string sub = s.substr(head, tail + 1);
 
      // Update the maximum
      mx = max(mx, a[sub.size() - 1] +
               maxScore(s.substr(0, head) +
                        s.substr(tail + 1,s.size()), a));
 
      // Move the tail
      tail += 1;
    }
    if (tail == n)
      break;
  }
 
  // Store the score
  dp[s] = mx;
  return mx;
}
 
// Driver Code
int main()
{
  string s = "abb";
  vector a = {1, 3, 1};
  cout<<(maxScore(s, a)-1);
}
 
// This code is contributed by mohit kumar 29.


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Initialize a dictionary to
// store the precomputed results
static Map dp = new HashMap<>();
 
// Function to calculate the maximum
// score possible by removing substrings
static int maxScore(String s, int[] a)
{
     
    // If s is present in dp[] array
    if (dp.containsKey(s))
        return dp.get(s);
 
    // Base Cases:
    int n = s.length();
 
    // If length of string is 0
    if (n == 0)
        return 0;
 
    // If length of string is 1
    if (n == 1)
        return a[0];
 
    // Put head pointer at start
    int head = 0;
 
    // Initialize the max variable
    int mx = -1;
 
    // Generate the substrings
    // using two pointers
    while (head < n)
    {
        int tail = head;
        while (tail < n)
        {
             
            // If s[head] and s[tail]
            // are different
            if (s.charAt(tail) != s.charAt(head))
            {
                 
                // Move head to
                // tail and break
                head = tail;
                break;
            }
 
            // Store the substring
            String sub = s.substring(head, tail + 1);
 
            // Update the maximum
            mx = Math.max(
                mx, a[sub.length() - 1] +
                maxScore(s.substring(0, head) +
                s.substring(tail + 1, s.length()), a));
 
            // Move the tail
            tail += 1;
        }
        if (tail == n)
            break;
    }
 
    // Store the score
    dp.put(s, mx);
    return mx;
}
 
// Driver code
public static void main(String[] args)
{
    String s = "abb";
    int[] a = { 1, 3, 1 };
     
    System.out.println((maxScore(s, a)));
}
}
 
// This code is contributed by offbeat


Python3
# Python program for the above approach
 
# Initialize a dictionary to
# store the precomputed results
dp = dict()
 
# Function to calculate the maximum
# score possible by removing substrings
def maxScore(s, a):
 
    # If s is present in dp[] array
    if s in dp:
        return dp[s]
 
    # Base Cases:
    n = len(s)
     
    # If length of string is 0
    if n == 0:
        return 0
       
    # If length of string is 1
    if n == 1:
        return a[0]
 
    # Put head pointer at start
    head = 0
 
    # Initialize the max variable
    mx = -1
 
    # Generate the substrings
    # using two pointers
    while head < n:
        tail = head
        while tail < n:
             
            # If s[head] and s[tail]
            # are different
            if s[tail] != s[head]:
               
                  # Move head to
                # tail and break
                head = tail
                break
             
            # Store the substring
            sub = s[head:tail + 1]
 
            # Update the maximum
            mx = max(mx, a[len(sub)-1]
                     + maxScore(s[:head] + s[tail + 1:], a))
 
            # Move the tail
            tail += 1
        if tail == n:
            break
 
    # Store the score
    dp[s] = mx
    return mx
 
 
# Driver Code
if __name__ == "__main__":
   
    s = "abb"
    a = [1, 3, 1]
 
    print(maxScore(s, a))


输出:
4

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

高效方法:为了优化上述方法,我们的想法是使用“记忆化”存储递归调用的结果,并使用“两个指针”技术存储仅包含1个不同字符的子字符串。
请按照以下步骤解决问题:

  • 声明一个递归函数,该函数将字符串作为输入来查找所需的结果。
  • 初始化一个数组,说dp []以记住结果。
    • 如果该值已经存储在数组dp []中,则返回结果。
    • 否则,请执行以下步骤:
      • 考虑基本情况,如果字符串的大小为0,则返回0 。如果等于1 ,则返回A [1]
      • 初始化一个变量,例如res ,以存储当前函数调用的结果。
      • 初始化两个指针,例如headtail ,分别表示子字符串的开始和结束索引。
      • 生成满足给定条件的子字符串,并为每个子字符串递归调用其余字符串的函数。将最大分数存储在res中
      • 将结果存储在dp []数组中并返回。
    • 打印由函数作为结果返回的值。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Initialize a dictionary to
// store the precomputed results
map dp;
 
// Function to calculate the maximum
// score possible by removing substrings
int maxScore(string s, vector a)
{
 
  // If s is present in dp[] array
  if (dp.find(s) != dp.end())
    return dp[s];
 
  // Base Cases:
  int n = s.size();
 
  // If length of string is 0
  if (n == 0)
    return 0;
 
  // If length of string is 1
  if (n == 1)
    return a[0];
 
  // Put head pointer at start
  int head = 0;
 
  // Initialize the max variable
  int mx = -1;
 
  // Generate the substrings
  // using two pointers
  while (head < n)
  {
    int tail = head;
    while (tail < n)
    {
 
      // If s[head] and s[tail]
      // are different
      if (s[tail] != s[head])
      {
 
        // Move head to
        // tail and break
        head = tail;
        break;
      }
 
      // Store the substring
      string sub = s.substr(head, tail + 1);
 
      // Update the maximum
      mx = max(mx, a[sub.size() - 1] +
               maxScore(s.substr(0, head) +
                        s.substr(tail + 1,s.size()), a));
 
      // Move the tail
      tail += 1;
    }
    if (tail == n)
      break;
  }
 
  // Store the score
  dp[s] = mx;
  return mx;
}
 
// Driver Code
int main()
{
  string s = "abb";
  vector a = {1, 3, 1};
  cout<<(maxScore(s, a)-1);
}
 
// This code is contributed by mohit kumar 29.

Java

// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Initialize a dictionary to
// store the precomputed results
static Map dp = new HashMap<>();
 
// Function to calculate the maximum
// score possible by removing substrings
static int maxScore(String s, int[] a)
{
     
    // If s is present in dp[] array
    if (dp.containsKey(s))
        return dp.get(s);
 
    // Base Cases:
    int n = s.length();
 
    // If length of string is 0
    if (n == 0)
        return 0;
 
    // If length of string is 1
    if (n == 1)
        return a[0];
 
    // Put head pointer at start
    int head = 0;
 
    // Initialize the max variable
    int mx = -1;
 
    // Generate the substrings
    // using two pointers
    while (head < n)
    {
        int tail = head;
        while (tail < n)
        {
             
            // If s[head] and s[tail]
            // are different
            if (s.charAt(tail) != s.charAt(head))
            {
                 
                // Move head to
                // tail and break
                head = tail;
                break;
            }
 
            // Store the substring
            String sub = s.substring(head, tail + 1);
 
            // Update the maximum
            mx = Math.max(
                mx, a[sub.length() - 1] +
                maxScore(s.substring(0, head) +
                s.substring(tail + 1, s.length()), a));
 
            // Move the tail
            tail += 1;
        }
        if (tail == n)
            break;
    }
 
    // Store the score
    dp.put(s, mx);
    return mx;
}
 
// Driver code
public static void main(String[] args)
{
    String s = "abb";
    int[] a = { 1, 3, 1 };
     
    System.out.println((maxScore(s, a)));
}
}
 
// This code is contributed by offbeat

Python3

# Python program for the above approach
 
# Initialize a dictionary to
# store the precomputed results
dp = dict()
 
# Function to calculate the maximum
# score possible by removing substrings
def maxScore(s, a):
 
    # If s is present in dp[] array
    if s in dp:
        return dp[s]
 
    # Base Cases:
    n = len(s)
     
    # If length of string is 0
    if n == 0:
        return 0
       
    # If length of string is 1
    if n == 1:
        return a[0]
 
    # Put head pointer at start
    head = 0
 
    # Initialize the max variable
    mx = -1
 
    # Generate the substrings
    # using two pointers
    while head < n:
        tail = head
        while tail < n:
             
            # If s[head] and s[tail]
            # are different
            if s[tail] != s[head]:
               
                  # Move head to
                # tail and break
                head = tail
                break
             
            # Store the substring
            sub = s[head:tail + 1]
 
            # Update the maximum
            mx = max(mx, a[len(sub)-1]
                     + maxScore(s[:head] + s[tail + 1:], a))
 
            # Move the tail
            tail += 1
        if tail == n:
            break
 
    # Store the score
    dp[s] = mx
    return mx
 
 
# Driver Code
if __name__ == "__main__":
   
    s = "abb"
    a = [1, 3, 1]
 
    print(maxScore(s, a))
输出:
4

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