📌  相关文章
📜  检查一个字符串可以分成两个相同的K频繁字符数的字符串

📅  最后修改于: 2021-04-21 21:55:34             🧑  作者: Mango

给定一个字符串S和整数K,任务是,以检查是否有可能这些字符分配到两个字符串,使得具有在两个字符串的频率k的字符计数等于。
如果可能的话,然后打印由12,其表示该字符应放置该字符串中的序列。否则,打印NO

注意:这些新字符串可以为空。

例子:

方法:
请按照以下步骤解决问题:

  • 检查以下三个条件以确定是否可以拆分:
    1. 如果在初始字符串频率为K的字符总数为偶数,则可以将这些字符均等地放入两个字符串,而其余字符(频率不等于K )可以放在两个字符串中的任何一个中组。
    2. 如果初始字符串具有频率K的字符总数为奇数,则如果初始字符串中存在一个频率大于K但不等于2K的字符,则这种分布是可能的。
    3. 如果在初始字符串具有频率K的字符总数为奇数,则在初始字符串具有频率等于2K的字符时,这种分布是可能的。
  • 如果上述三个条件均失败,则答案为“否”

下面是上述方法的实现:

C++
// C++ implementation of the
// above approach
#include 
using namespace std;
  
// Function to print the
// arrangement of characters
void DivideString(string s, int n,
                  int k)
{
    int i, c = 0, no = 1;
    int c1 = 0, c2 = 0;
  
    // Stores frequency of
    // characters
    int fr[26] = { 0 };
  
    string ans = "";
  
    for (i = 0; i < n; i++) {
        fr[s[i] - 'a']++;
    }
  
    char ch, ch1;
    for (i = 0; i < 26; i++) {
  
        // Count the character
        // having frequency K
        if (fr[i] == k) {
            c++;
        }
  
        // Count the character
        // having frequency
        // greater than K and
        // not equal to 2K
        if (fr[i] > k
            && fr[i] != 2 * k) {
            c1++;
            ch = i + 'a';
        }
  
        if (fr[i] == 2 * k) {
            c2++;
            ch1 = i + 'a';
        }
    }
  
    for (i = 0; i < n; i++)
        ans = ans + "1";
  
    map mp;
    if (c % 2 == 0 || c1 > 0 || c2 > 0) {
        for (i = 0; i < n; i++) {
  
            // Case 1
            if (fr[s[i] - 'a'] == k) {
                if (mp.find(s[i])
                    != mp.end()) {
                    ans[i] = '2';
                }
                else {
                    if (no <= (c / 2)) {
                        ans[i] = '2';
                        no++;
                        mp[s[i]] = 1;
                    }
                }
            }
        }
  
        // Case 2
        if (c % 2 == 1 && c1 > 0) {
            no = 1;
            for (i = 0; i < n; i++) {
                if (s[i] == ch && no <= k) {
  
                    ans[i] = '2';
                    no++;
                }
            }
        }
  
        // Case 3
        if (c % 2 == 1 && c1 == 0) {
            no = 1;
            int flag = 0;
            for (int i = 0; i < n; i++) {
                if (s[i] == ch1 && no <= k) {
                    ans[i] = '2';
                    no++;
                }
                if (fr[s[i] - 'a'] == k
                    && flag == 0
                    && ans[i] == '1') {
                    ans[i] = '2';
                    flag = 1;
                }
            }
        }
  
        cout << ans << endl;
    }
    else {
        // If all cases fail
        cout << "NO" << endl;
    }
}
  
// Driver Code
int main()
{
  
    string S = "abbbccc";
    int N = S.size();
    int K = 1;
  
    DivideString(S, N, K);
  
    return 0;
}


Java
// Java program for the above problem 
import java.util.*; 
  
class GFG{
      
// Function to print the 
// arrangement of characters 
public static void DivideString(String s, int n, 
                                          int k) 
{ 
    int i, c = 0, no = 1; 
    int c1 = 0, c2 = 0; 
  
    // Stores frequency of 
    // characters 
    int[] fr = new int[26]; 
  
    char[] ans = new char[n]; 
  
    for(i = 0; i < n; i++)
    { 
        fr[s.charAt(i) - 'a']++; 
    } 
  
    char ch = 'a', ch1 = 'a'; 
    for(i = 0; i < 26; i++)
    { 
          
        // Count the character 
        // having frequency K 
        if (fr[i] == k) 
        { 
            c++; 
        } 
  
        // Count the character 
        // having frequency 
        // greater than K and 
        // not equal to 2K 
        if (fr[i] > k && fr[i] != 2 * k)
        { 
            c1++; 
            ch = (char)(i + 'a'); 
        } 
  
        if (fr[i] == 2 * k) 
        { 
            c2++; 
            ch1 = (char)(i + 'a'); 
        } 
    } 
  
    for(i = 0; i < n; i++) 
        ans[i] = '1'; 
      
    HashMap mp = new HashMap<>(); 
  
    if (c % 2 == 0 || c1 > 0 || c2 > 0)
    { 
        for(i = 0; i < n; i++) 
        { 
  
            // Case 1 
            if (fr[s.charAt(i) - 'a'] == k) 
            { 
                if (mp.containsKey(s.charAt(i)))
                { 
                    ans[i] = '2'; 
                } 
                else 
                { 
                    if (no <= (c / 2))
                    { 
                        ans[i] = '2'; 
                        no++; 
                        mp.replace(s.charAt(i), 1);
                    } 
                } 
            } 
        } 
  
        // Case 2 
        if ( (c % 2 == 1) && (c1 > 0) )
        { 
            no = 1; 
            for(i = 0; i < n; i++)
            { 
                if (s.charAt(i) == ch && no <= k) 
                { 
                    ans[i] = '2'; 
                    no++; 
                } 
            } 
        } 
  
        // Case 3 
        if (c % 2 == 1 && c1 == 0) 
        { 
            no = 1; 
            int flag = 0; 
              
            for(i = 0; i < n; i++)
            { 
                if (s.charAt(i) == ch1 && no <= k) 
                { 
                    ans[i] = '2'; 
                    no++; 
                } 
                if (fr[s.charAt(i) - 'a'] == k && 
                      flag == 0 && ans[i] == '1')
                { 
                    ans[i] = '2'; 
                    flag = 1; 
                } 
            } 
        } 
        System.out.println(ans);
    } 
    else
    {
          
        // If all cases fail
        System.out.println("NO");
    } 
} 
  
// Driver code
public static void main(String[] args)
{
    String S = "abbbccc"; 
    int N = S.length(); 
    int K = 1; 
  
    DivideString(S, N, K); 
}
}
  
// This code is contributed by divyeshrabadiya07


Python3
# Python3 implementation of the
# above approach
  
# Function to print the
# arrangement of characters
def DivideString(s, n, k):
      
    c = 0
    no = 1
    c1 = 0
    c2 = 0
  
    # Stores frequency of
    # characters
    fr = [0] * 26
  
    ans = []
    for i in range(n):
        fr[ord(s[i]) - ord('a')] += 1
  
    for i in range(26):
  
        # Count the character
        # having frequency K
        if (fr[i] == k):
            c += 1
  
        # Count the character having
        # frequency greater than K and
        # not equal to 2K
        if (fr[i] > k and fr[i] != 2 * k):
            c1 += 1
            ch = chr(ord('a') + i)
  
        if (fr[i] == 2 * k):
            c2 += 1
            ch1 = chr(ord('a') + i)
  
    for i in range(n):
        ans.append("1")
  
    mp = {}
    if (c % 2 == 0 or c1 > 0 or c2 > 0):
        for i in range(n):
              
            # Case 1
            if (fr[ord(s[i]) - ord('a')] == k):
                if (s[i] in mp):
                    ans[i] = '2'
  
                else:
                    if (no <= (c // 2)):
                        ans[i] = '2'
                        no += 1
                        mp[s[i]] = 1
                          
        # Case 2
        if (c % 2 == 1 and c1 > 0):
            no = 1
            for i in range(n):
                if (s[i] == ch and no <= k):
                    ans[i] = '2'
                    no += 1
                      
        # Case 3
        if (c % 2 == 1 and c1 == 0):
            no = 1
            flag = 0
              
            for i in range(n):
                if (s[i] == ch1 and no <= k):
                    ans[i] = '2'
                    no += 1
                      
                if (fr[s[i] - 'a'] == k and 
                              flag == 0 and 
                            ans[i] == '1'):
                    ans[i] = '2'
                    flag = 1
  
        print("".join(ans))
    else:
          
        # If all cases fail
        print("NO")
  
# Driver Code
if __name__ == '__main__':
  
    S = "abbbccc"
    N = len(S)
    K = 1
  
    DivideString(S, N, K)
  
# This code is contributed by mohit kumar 29


C#
// C# program for the above problem 
using System; 
using System.Collections.Generic; 
  
class GFG{ 
      
// Function to print the 
// arrangement of characters 
public static void DivideString(string s, int n, 
                                          int k) 
{ 
    int i, c = 0, no = 1; 
    int c1 = 0, c2 = 0; 
  
    // Stores frequency of 
    // characters 
    int[] fr = new int[26]; 
  
    char[] ans = new char[n]; 
  
    for(i = 0; i < n; i++) 
    { 
        fr[s[i] - 'a']++; 
    } 
  
    char ch = 'a', ch1 = 'a'; 
    for(i = 0; i < 26; i++) 
    { 
          
        // Count the character 
        // having frequency K 
        if (fr[i] == k) 
        { 
            c++; 
        } 
  
        // Count the character having 
        // frequency greater than K and 
        // not equal to 2K 
        if (fr[i] > k && fr[i] != 2 * k) 
        { 
            c1++; 
            ch = (char)(i + 'a'); 
        } 
  
        if (fr[i] == 2 * k) 
        { 
            c2++; 
            ch1 = (char)(i + 'a'); 
        } 
    } 
  
    for(i = 0; i < n; i++) 
        ans[i] = '1'; 
      
    Dictionary mp = new Dictionary(); 
  
    if (c % 2 == 0 || c1 > 0 || c2 > 0) 
    { 
        for(i = 0; i < n; i++) 
        { 
  
            // Case 1 
            if (fr[s[i] - 'a'] == k) 
            { 
                if (mp.ContainsKey(s[i])) 
                { 
                    ans[i] = '2'; 
                } 
                else
                { 
                    if (no <= (c / 2)) 
                    { 
                        ans[i] = '2'; 
                        no++; 
                        mp[s[i]] = 1;
                    } 
                } 
            } 
        } 
  
        // Case 2 
        if ( (c % 2 == 1) && (c1 > 0) ) 
        { 
            no = 1; 
            for(i = 0; i < n; i++) 
            { 
                if (s[i]== ch && no <= k) 
                { 
                    ans[i] = '2'; 
                    no++; 
                } 
            } 
        } 
  
        // Case 3 
        if (c % 2 == 1 && c1 == 0) 
        { 
            no = 1; 
            int flag = 0; 
              
            for(i = 0; i < n; i++) 
            { 
                if (s[i] == ch1 && no <= k) 
                { 
                    ans[i] = '2'; 
                    no++; 
                } 
                if (fr[s[i] - 'a'] == k && 
                    flag == 0 && ans[i] == '1') 
                { 
                    ans[i] = '2'; 
                    flag = 1; 
                } 
            } 
        } 
        Console.Write(ans); 
    } 
    else
    { 
          
        // If all cases fail 
        Console.Write("NO"); 
    } 
} 
  
// Driver code 
public static void Main(string[] args) 
{ 
    string S = "abbbccc"; 
    int N = S.Length; 
    int K = 1; 
  
    DivideString(S, N, K); 
} 
} 
  
// This code is contributed by rutvik_56


输出:
1111211

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