📌  相关文章
📜  最小化替换次数,以获得其中具有相同数字“ a”,“ b”和“ c”的字符串

📅  最后修改于: 2021-06-26 11:57:43             🧑  作者: Mango

给定一个仅包含三个可能字符“ a”,“ b”或“ c”的字符串。该任务是与“A”,“b”或“c”来替换给定的字符串的字符仅使得存在的字符串中“A”,“b”和“c”的字符的数目相等。任务是最大程度地减少替换次数,并以最少的替换打印所有此类字符串按字典顺序最小的字符串。

如果无法获得这样的字符串,请打印-1。

例子:

Input : s = "bcabba"
Output : bcabca
Number of replacements done is 1 and this is
the lexicographically smallest possible 

Input : "aaaaaa"
Output : aabbcc

Input : "aaaaa"
Output : -1

方法:

  • 计算字符串中“ a”,“ b”和“ c”的数量。
  • 如果它们的数量相等,则答案是相同的字符串。
  • 如果字符串的长度不是3的倍数,则不可能。
  • 首先,减少字符串中超过a的数目。
    1. 如果使用左侧的滑动窗口技术,如果将“ c”替换为“ a”,则将其替换为“ a”。
    2. 如果在索引处没有“ c”的情况下使用左向左滑动窗口技术,则将“ b”替换为“ a”。
  • 其次,通过使用滑动窗口从前面替换“ c”来减少字符串中超过b的数目。
  • 第三,通过使用滑动窗口减少背面多余的“ a”的数量,减少超过c的数量。
  • 第四,通过减少后面多余的“ a”的数量来减少字符串中超过b的数量。
  • 第五,通过减少背面多余的“ b”的数量来减少超过c的数量。

为了得到字典上最小的字符串,我们不断从后面进行替换。

下面是上述方法的实现:

C++
// CPP program to Minimize the number of
// replacements to get a string with same
// number of ‘a’, ‘b’ and ‘c’ in it
  
#include 
using namespace std;
  
// Function to count numbers
string lexoSmallest(string s, int n)
{
    // Count the number of 'a', 'b' and
    // 'c' in string
    int ca = 0, cb = 0, cc = 0;
  
    for (int i = 0; i < n; i++) {
        if (s[i] == 'a')
            ca++;
        else if (s[i] == 'b')
            cb++;
        else
            cc++;
    }
  
    // If equal previously
    if (ca == cb && cb == cc) {
        return s;
    }
  
    int cnt = n / 3;
  
    // If not a multiple of 3
    if (cnt * 3 != n) {
        return "-1";
    }
  
    int i = 0;
  
    // Increase the number of a's by
    // removing extra 'b' and ;c;
    while (ca < cnt && i < n) {
  
        // Check if it is 'b' and it more
        // than n/3
        if (s[i] == 'b' && cb > cnt) {
            cb--;
            s[i] = 'a';
            ca++;
        }
  
        // Check if it is 'c' and it
        // more than n/3
        else if (s[i] == 'c' && cc > cnt) {
            cc--;
            s[i] = 'a';
            ca++;
        }
  
        i++;
    }
  
    i = 0;
  
    // Increase the number of b's by
    // removing extra 'c'
    while (cb < cnt && i < n) {
  
        // Check if it is 'c' and it more
        // than n/3
        if (s[i] == 'c' && cc > cnt) {
            cc--;
            s[i] = '1';
  
            cb++;
        }
        i++;
    }
  
    i = n - 1;
  
    // Increase the number of c's from back
    while (cc < cnt && i >= 0) {
  
        // Check if it is 'a' and it more
        // than n/3
        if (s[i] == 'a' && ca > cnt) {
            ca--;
            s[i] = 'c';
            cc++;
        }
  
        i--;
    }
  
    i = n - 1;
  
    // Increase the number of b's from back
    while (cb < cnt && i >= 0) {
  
        // Check if it is 'a' and it more
        // than n/3
        if (s[i] == 'a' && ca > cnt) {
            ca--;
            s[i] = 'b';
            cb++;
        }
  
        i--;
    }
  
    i = n - 1;
  
    // Increase the number of c's from back
    while (cc < cnt && i >= 0) {
  
        // Check if it is 'b' and it more
        // than n/3
        if (s[i] == 'b' && cb > cnt) {
            cb--;
            s[i] = 'c';
            cc++;
        }
  
        i--;
    }
  
    return s;
}
  
// Driver Code
int main()
{
    string s = "aaaaaa";
    int n = s.size();
  
    cout << lexoSmallest(s, n);
  
    return 0;
}


Python3
# Python3 program to Minimize the number of
# replacements to get a string with same
# number of 'a', 'b' and 'c' in it
  
# Function to count numbers
def lexoSmallest(s, n):
      
    # Count the number of 'a', 'b' and
    # 'c' in string
    ca = 0
    cb = 0
    cc = 0
    for i in range(n):
        if (s[i] == 'a'):
            ca += 1
        elif (s[i] == 'b'):
            cb += 1
        else:
            cc += 1
      
    # If equal previously
    if (ca == cb and cb == cc):
        return s
          
    cnt = n // 3
      
    # If not a multiple of 3
    if (cnt * 3 != n):
        return "-1"
          
    i = 0
      
    # Increase the number of a's by
    # removing extra 'b' and c
    while (ca < cnt and i < n):
          
        # Check if it is 'b' and it more
        # than n/3
        if (s[i] == 'b' and cb > cnt) :
            cb -= 1
            s[i] = 'a'
            ca += 1
              
        # Check if it is 'c' and it
        # more than n/3
        elif (s[i] == 'c' and cc > cnt):
            cc -= 1
            s[i] = 'a'
            ca += 1
              
        i += 1
    i = 0
      
    # Increase the number of b's by
    # removing extra 'c'
    while (cb < cnt and i < n):
          
        # Check if it is 'c' and it more
        # than n/3
        if (s[i] == 'c' and cc > cnt):
            cc -= 1
            s[i] = '1'
            cb += 1
          
        i += 1
      
    i = n - 1
      
    # Increase the number of c's from back
    while (cc < cnt and i >= 0):
          
        # Check if it is 'a' and it more
        # than n/3
        if (s[i] == 'a' and ca > cnt):
            ca -= 1
            s[i] = 'c'
            cc += 1
          
        i -= 1
      
    i = n - 1
      
    # Increase the number of b's from back
    while (cb < cnt and i >= 0):
         
        # Check if it is 'a' and it more
        # than n/3
        if (s[i] == 'a' and ca > cnt):
            ca -= 1
            s[i] = 'b'
            cb += 1
              
        i -= 1
          
    i = n - 1
      
    # Increase the number of c's from back
    while (cc < cnt and i >= 0):
          
        # Check if it is 'b' and it more
        # than n/3
        if (s[i] == 'b' and cb > cnt):
            cb -= 1
            s[i] = 'c'
            cc += 1
          
        i -= 1
    return s
  
# Driver Code
  
s = "aaaaaa"
n = len(s)
  
print(*lexoSmallest(list(s), n),sep="")
  
# This code is contributed by shivanisinghss2110


C#
// C# program to minimize the number of
// replacements to get a string with same
// number of ‘a’, ‘b’ and ‘c’ in it
using System;
using System.Text; 
  
class GFG{
      
// Function to count numbers
static string lexoSmallest(string str, int n)
{
      
    // Count the number of 'a', 'b' and
    // 'c' in string
    int ca = 0, cb = 0, cc = 0;
    StringBuilder s = new StringBuilder(str); 
  
    for(int j = 0; j < n; j++)
    {
        if (s[j] == 'a')
            ca++;
        else if (s[j] == 'b')
            cb++;
        else
            cc++;
    }
  
    // If equal previously
    if (ca == cb && cb == cc) 
    {
        return s.ToString();
    }
  
    int cnt = n / 3;
  
    // If not a multiple of 3
    if (cnt * 3 != n)
    {
        return "-1";
    }
  
    int i = 0;
  
    // Increase the number of a's by
    // removing extra 'b' and ;c;
    while (ca < cnt && i < n)
    {
          
        // Check if it is 'b' and it more
        // than n/3
        if (s[i] == 'b' && cb > cnt)
        {
            cb--;
            s[i] = 'a';
            ca++;
        }
  
        // Check if it is 'c' and it
        // more than n/3
        else if (s[i] == 'c' && cc > cnt)
        {
            cc--;
            s[i] = 'a';
            ca++;
        }
        i++;
    }
  
    i = 0;
  
    // Increase the number of b's by
    // removing extra 'c'
    while (cb < cnt && i < n)
    {
          
        // Check if it is 'c' and it more
        // than n/3
        if (s[i] == 'c' && cc > cnt) 
        {
            cc--;
            s[i] = '1';
  
            cb++;
        }
        i++;
    }
  
    i = n - 1;
  
    // Increase the number of c's from back
    while (cc < cnt && i >= 0) 
    {
          
        // Check if it is 'a' and it more
        // than n/3
        if (s[i] == 'a' && ca > cnt)
        {
            ca--;
            s[i] = 'c';
            cc++;
        }
        i--;
    }
  
    i = n - 1;
  
    // Increase the number of b's from back
    while (cb < cnt && i >= 0)
    {
          
        // Check if it is 'a' and it more
        // than n/3
        if (s[i] == 'a' && ca > cnt)
        {
            ca--;
            s[i] = 'b';
            cb++;
        }
        i--;
    }
  
    i = n - 1;
  
    // Increase the number of c's from back
    while (cc < cnt && i >= 0)
    {
          
        // Check if it is 'b' and it more
        // than n/3
        if (s[i] == 'b' && cb > cnt) 
        {
            cb--;
            s[i] = 'c';
            cc++;
        }
        i--;
    }
    return s.ToString();
} 
      
// Driver Code
public static void Main(string[] args)
{
    string s = "aaaaaa";
    int n = s.Length;
      
    Console.Write(lexoSmallest(s, n));
}
}
  
// This code is contributed by rutvik_56


PHP
 $cnt) 
        { 
            $cb--; 
            $s[$i] = 'a'; 
            $ca++; 
        } 
  
        // Check if it is 'c' and it 
        // more than n/3 
        else if ($s[$i] == 'c' && $cc > $cnt) 
        { 
            $cc--; 
            $s[$i] = 'a'; 
            $ca++; 
        } 
  
        $i++; 
    } 
  
    $i = 0; 
  
    // Increase the number of b's by 
    // removing extra 'c' 
    while ($cb < $cnt && $i < $n) 
    { 
  
        // Check if it is 'c' and it more 
        // than n/3 
        if ($s[$i] == 'c' && $cc > $cnt) 
        { 
            $cc--; 
            $s[$i] = '1'; 
  
            $cb++; 
        } 
        $i++; 
    } 
  
    $i = $n - 1; 
  
    // Increase the number of c's from back 
    while ($cc < $cnt && $i >= 0) 
    { 
  
        // Check if it is 'a' and it is 
        // more than n/3 
        if ($s[$i] == 'a' && $ca > $cnt) 
        { 
            $ca--; 
            $s[$i] = 'c'; 
            $cc++; 
        } 
  
        $i--; 
    } 
  
    $i = $n - 1; 
  
    // Increase the number of b's from back 
    while ($cb < $cnt && $i >= 0) 
    { 
  
        // Check if it is 'a' and it is 
        // more than n/3 
        if ($s[$i] == 'a' && $ca > $cnt) 
        { 
            $ca--; 
            $s[$i] = 'b'; 
            $cb++; 
        } 
  
        $i--; 
    } 
  
    $i = $n - 1; 
  
    // Increase the number of c's from back 
    while ($cc < $cnt && $i >= 0) 
    { 
  
        // Check if it is 'b' and it more 
        // than n/3 
        if ($s[$i] == 'b' && $cb > $cnt) 
        { 
            $cb--; 
            $s[$i] = 'c'; 
            $cc++; 
        } 
  
        $i--; 
    } 
  
    return $s; 
} 
  
// Driver Code 
$s = "aaaaaa"; 
$n = strlen($s); 
  
echo lexoSmallest($s, $n);
  
// This code is contributed by Ryuga.
?>
  

Output:aabbcc
Time Complexity: O(N*6)In case you wish to attend live classes with industry experts, please refer Geeks Classes Live and Geeks Classes Live USA