📜  修改字符串的最低成本

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

修改字符串的最低成本

给定字符串str仅由小写字母和整数K组成。任务是找到修改字符串的最小成本,以使给定字符串的任意两个字符之间的 ASCII 值差异小于等于K。
可以对字符串执行以下操作:

  1. 增加一个字符:例如,当您将'a'增加1时,它变为'b' 。同样,如果将'z'增加1 ,它会变为'a' 。增量以循环方式完成。
  2. 减少一个字符:例如,当您将'a'减少1时,它变为'z' 。同样,如果将'z'1 ,它会变为'y' 。递减是以循环方式进行的。

例子:

方法:这个想法是为字符串的所有字符维护一个哈希表,以降低时间复杂度,而不是一次取一个字符。我们需要检查所有包含 k 个连续字符的窗口,并在所有窗口中找到修改字符串所有字符的最小成本。
字符修改成本分为以下几类:

  • 情况1:如果字符在窗口内,修改它们不会产生任何费用。
  • 情况 2:如果窗口在字符az 之间,而字符在窗口的左侧。

  • 如果我们增加将产生 d1 成本的字符,或者如果我们减少将产生 d2+d3 成本的字符,我们会找到 d1 和 d2+d3 的最小值。
    如果窗口在字符az 之间并且字符在窗口的右侧。

  • 如果我们减少将产生 d1 成本的字符,或者如果我们增加将产生 d2+d3 成本的字符,我们会找到 d1 和 d2+d3 的最小值。
  • 情况 3:如果窗口是一个以 z 结尾并从 a 开始的字符的子窗口,并且该字符在窗口之外。

  • 如果我们增加字符,它将产生 d1 的成本,如果我们减少字符,它将产生 d2 的成本,我们在 d1 和 d2 之间找到最小值。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the minimum cost
int minCost(string str, int K)
{
    int n = str.length();
 
    // Initialize result
    int res = 999999999, count = 0, a, b;
 
    // To store the frequency of characters
    // of the string
    int cnt[27];
 
    // Initialize array with 0
    memset(cnt, 0, sizeof(cnt));
 
    // Update the frequencies of the
    // characters of the string
    for (int i = 0; i < n; i++)
        cnt[str[i] - 'a' + 1]++;
 
    // Loop to check all windows from a-z
    // where window size is K
    for (int i = 1; i < (26 - K + 1); i++) {
 
        // Starting index of window
        a = i;
 
        // Ending index of window
        b = i + K;
        count = 0;
        for (int j = 1; j <= 26; j++) {
 
            // Check if the string contains character
            if (cnt[j] > 0) {
 
                // Check if the character is on left side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                if (j >= a && j >= b)
                    count = count + (min(j - b, 25 - j + a + 1)) * cnt[j];
 
                // Check if the character is on right side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                else if (j <= a && j <= b)
                    count = count + (min(a - j, 25 + j - b + 1)) * cnt[j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        res = min(res, count);
    }
 
    // Loop to check all windows
    // Here window contains characters
    // before z and after z of window size K
    for (int i = 26 - K + 1; i <= 26; i++) {
 
        // Starting index of window
        a = i;
 
        // Ending index of window
        b = (i + K) % 26;
        count = 0;
 
        for (int j = 1; j <= 26; j++) {
 
            // Check if the string contains character
            if (cnt[j] > 0) {
 
                // If characters are outside window
                // find the cost for modifying character
                // add value to count
                if (j >= b and j <= a)
                    count = count + (min(j - b, a - j)) * cnt[j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        res = min(res, count);
    }
 
    return res;
}
 
// Driver code
int main()
{
    string str = "abcdefghi";
    int K = 2;
    cout << minCost(str, K);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.Arrays;
 
class GFG
{
 
// Function to return the minimum cost
static int minCost(String str, int K)
{
    int n = str.length();
 
    // Initialize result
    int res = 999999999, count = 0, a, b;
 
    // To store the frequency of characters
    // of the string
    int cnt[] = new int[27];
 
    // Initialize array with 0
    Arrays.fill(cnt, 0);
 
    // Update the frequencies of the
    // characters of the string
    for (int i = 0; i < n; i++)
        cnt[str.charAt(i) - 'a' + 1]++;
 
    // Loop to check all windows from a-z
    // where window size is K
    for (int i = 1; i < (26 - K + 1); i++)
    {
 
        // Starting index of window
        a = i;
 
        // Ending index of window
        b = i + K;
        count = 0;
        for (int j = 1; j <= 26; j++)
        {
 
            // Check if the string contains character
            if (cnt[j] > 0)
            {
 
                // Check if the character is on left side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                if (j >= a && j >= b)
                    count = count + (Math.min(j - b,
                            25 - j + a + 1)) * cnt[j];
 
                // Check if the character is on right side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                else if (j <= a && j <= b)
                    count = count + (Math.min(a - j,
                            25 + j - b + 1)) * cnt[j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        res = Math.min(res, count);
    }
 
    // Loop to check all windows
    // Here window contains characters
    // before z and after z of window size K
    for (int i = 26 - K + 1; i <= 26; i++)
    {
 
        // Starting index of window
        a = i;
 
        // Ending index of window
        b = (i + K) % 26;
        count = 0;
 
        for (int j = 1; j <= 26; j++)
        {
 
            // Check if the string contains character
            if (cnt[j] > 0)
            {
 
                // If characters are outside window
                // find the cost for modifying character
                // add value to count
                if (j >= b && j <= a)
                    count = count + (Math.min(j - b, a - j)) * cnt[j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        res = Math.min(res, count);
    }
 
    return res;
}
 
// Driver code
public static void main(String[] args)
{
    String str = "abcdefghi";
    int K = 2;
    System.out.println(minCost(str, K));
}
}
 
/* This code contributed by PrinciRaj1992 */


Python3
# Python 3 implementation of the approach
 
# Function to return the minimum cost
def minCost(str1, K):
    n = len(str1)
 
    # Initialize result
    res = 999999999
    count = 0
 
    # To store the frequency of characters
    # of the string
    cnt = [0 for i in range(27)]
 
    # Update the frequencies of the
    # characters of the string
    for i in range(n):
        cnt[ord(str1[i]) - ord('a') + 1] += 1
 
    # Loop to check all windows from a-z
    # where window size is K
    for i in range(1, 26 - K + 1, 1):
        # Starting index of window
        a = i
 
        # Ending index of window
        b = i + K
        count = 0
        for j in range(1, 27, 1):
             
            # Check if the string contains character
            if (cnt[j] > 0):
                 
                # Check if the character is on left side of window
                # find the cost of modification for character
                # add value to count
                # calculate nearest distance of modification
                if (j >= a and j >= b):
                    count = count + (min(j - b, 25 -
                                         j + a + 1)) * cnt[j]
 
                # Check if the character is on right side of window
                # find the cost of modification for character
                # add value to count
                # calculate nearest distance of modification
                elif (j <= a and j <= b):
                    count = count + (min(a - j, 25 +
                                             j - b + 1)) * cnt[j]
 
        # Find the minimum of all costs
        # for modifying the string
        res = min(res, count)
 
    # Loop to check all windows
    # Here window contains characters
    # before z and after z of window size K
    for i in range(26 - K + 1, 27, 1):
         
        # Starting index of window
        a = i
 
        # Ending index of window
        b = (i + K) % 26
        count = 0
 
        for j in range(1, 27, 1):
             
            # Check if the string contains character
            if (cnt[j] > 0):
                 
                # If characters are outside window
                # find the cost for modifying character
                # add value to count
                if (j >= b and j <= a):
                    count = count + (min(j - b,
                                         a - j)) * cnt[j]
 
        # Find the minimum of all costs
        # for modifying the string
        res = min(res, count)
 
    return res
 
# Driver code
if __name__ == '__main__':
    str1 = "abcdefghi"
    K = 2
    print(minCost(str1, K))
 
# This code is contributed by
# Surendra_Gangwar


C#
// C# program to implement
// the above approach
using System;
 
class GFG
{
 
// Function to return the minimum cost
static int minCost(String str, int K)
{
    int n = str.Length;
 
    // Initialize result
    int res = 999999999, count = 0, a, b;
 
    // To store the frequency of characters
    // of the string
    int []cnt = new int[27];
 
 
    // Update the frequencies of the
    // characters of the string
    for (int i = 0; i < n; i++)
        cnt[str[i] - 'a' + 1]++;
 
    // Loop to check all windows from a-z
    // where window size is K
    for (int i = 1; i < (26 - K + 1); i++)
    {
 
        // Starting index of window
        a = i;
 
        // Ending index of window
        b = i + K;
        count = 0;
        for (int j = 1; j <= 26; j++)
        {
 
            // Check if the string contains character
            if (cnt[j] > 0)
            {
 
                // Check if the character is on left side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                if (j >= a && j >= b)
                    count = count + (Math.Min(j - b,
                            25 - j + a + 1)) * cnt[j];
 
                // Check if the character is on right side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                else if (j <= a && j <= b)
                    count = count + (Math.Min(a - j,
                            25 + j - b + 1)) * cnt[j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        res = Math.Min(res, count);
    }
 
    // Loop to check all windows
    // Here window contains characters
    // before z and after z of window size K
    for (int i = 26 - K + 1; i <= 26; i++)
    {
 
        // Starting index of window
        a = i;
 
        // Ending index of window
        b = (i + K) % 26;
        count = 0;
 
        for (int j = 1; j <= 26; j++)
        {
 
            // Check if the string contains character
            if (cnt[j] > 0)
            {
 
                // If characters are outside window
                // find the cost for modifying character
                // add value to count
                if (j >= b && j <= a)
                    count = count + (Math.Min(j - b, a - j)) * cnt[j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        res = Math.Min(res, count);
    }
 
    return res;
}
 
// Driver code
public static void Main(String[] args)
{
    String str = "abcdefghi";
    int K = 2;
    Console.WriteLine(minCost(str, K));
}
}
 
// This code has been contributed by 29AjayKumar


PHP
 0)
            {
 
                // Check if the character is on left side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                if ($j >= $a && $j >= $b)
                    $count = $count + (min($j - $b, 25 - $j + $a + 1)) * $cnt[$j];
 
                // Check if the character is on right side of window
                // find the cost of modification for character
                // add value to count
                // calculate nearest distance of modification
                else if ($j <= $a && $j <=$b)
                    $count = $count + (min($a - $j, 25 + $j - $b + 1)) * $cnt[$j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        $res = min($res, $count);
    }
 
    // Loop to check all windows
    // Here window contains characters
    // before z and after z of window size K
    for ($i = 26 - $K + 1; $i <= 26; $i++)
    {
 
        // Starting index of window
        $a = $i;
 
        // Ending index of window
        $b = ($i + $K) % 26;
        $count = 0;
 
        for ($j = 1; $j <= 26; $j++)
        {
 
            // Check if the string contains character
            if ($cnt[$j] > 0)
            {
 
                // If characters are outside window
                // find the cost for modifying character
                // add value to count
                if ($j >= $b and $j <= $a)
                    $count = $count + (min($j - $b,$a - $j)) * $cnt[$j];
            }
        }
 
        // Find the minimum of all costs
        // for modifying the string
        $res = min($res, $count);
    }
 
    return $res;
}
 
    // Driver code
    $str = "abcdefghi";
    $K = 2;
    echo minCost($str, $K);
     
    // This code is contributed by Ryuga
 
?>


Javascript


输出:
12

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