修改字符串的最低成本
给定字符串str仅由小写字母和整数K组成。任务是找到修改字符串的最小成本,以使给定字符串的任意两个字符之间的 ASCII 值差异小于等于K。
可以对字符串执行以下操作:
- 增加一个字符:例如,当您将'a'增加1时,它变为'b' 。同样,如果将'z'增加1 ,它会变为'a' 。增量以循环方式完成。
- 减少一个字符:例如,当您将'a'减少1时,它变为'z' 。同样,如果将'z'减1 ,它会变为'y' 。递减是以循环方式进行的。
例子:
Input: str = “abcd”, K = 1
Output: 2
Change ‘a’ to ‘b’ with cost 1 and ‘d’ to ‘c’ again at cost 1.
Total cost = 1 + 1 = 2.
The modified string will be “bbcc”
Input: str = “abcdefghi”, K = 2
Output: 12
方法:这个想法是为字符串的所有字符维护一个哈希表,以降低时间复杂度,而不是一次取一个字符。我们需要检查所有包含 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)