📌  相关文章
📜  将字符串划分为两个子字符串具有最大数量的公共非重复字符

📅  最后修改于: 2021-04-17 11:21:19             🧑  作者: Mango

给定字符串str ,任务是找到可以通过将给定字符串划分为两个非空子字符串获得的常见非重复字符的最大数量。

例子:

天真的方法:解决此问题的最简单方法是遍历字符串的字符,然后在每个可能的索引处将字符串分成两个非空子字符串,并计算两个子字符串中重复的字符数。打印获得的最大计数。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the string into two non-empty substrings
int countCommonChar(int ind, string& S)
{
 
    // Stores count of non-repeating characters
    // present in both the substrings
    int cnt = 0;
 
    // Stores distinct characters
    // in left substring
    set ls;
 
    // Stores distinct characters
    // in right substring
    set rs;
 
    // Traverse left substring
    for (int i = 0; i < ind; ++i) {
 
        // Insert S[i] into ls
        ls.insert(S[i]);
    }
 
    // Traverse right substring
    for (int i = ind; i < S.length();
         ++i) {
 
        // Insert S[i] into rs
        rs.insert(S[i]);
    }
 
    // Traverse distinct characters
    // of left substring
    for (auto v : ls) {
 
        // If current character is
        // present in right substring
        if (rs.count(v)) {
 
            // Update cnt
            ++cnt;
        }
    }
 
    // Return count
    return cnt;
}
 
// Function to partition the string into
// two non-empty substrings in all possible ways
void partitionStringWithMaxCom(string& S)
{
    // Stores maximum common distinct characters
    // present in both the substring partitions
    int ans = 0;
 
    // Traverse the string
    for (int i = 1; i < S.length(); ++i) {
 
        // Update ans
        ans = max(ans,
                  countCommonChar(i, S));
    }
 
    // Print count of maximum common
    // non-repeating characters
    cout << ans << "\n";
}
 
// Driver Code
int main()
{
    string str = "aabbca";
 
    partitionStringWithMaxCom(str);
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the String into two non-empty subStrings
static int countCommonChar(int ind, String S)
{
 
    // Stores count of non-repeating characters
    // present in both the subStrings
    int cnt = 0;
 
    // Stores distinct characters
    // in left subString
    HashSet ls = new HashSet();
 
    // Stores distinct characters
    // in right subString
    HashSet rs = new HashSet();
 
    // Traverse left subString
    for (int i = 0; i < ind; ++i) {
 
        // Insert S[i] into ls
        ls.add(S.charAt(i));
    }
 
    // Traverse right subString
    for (int i = ind; i < S.length();
         ++i) {
 
        // Insert S[i] into rs
        rs.add(S.charAt(i));
    }
 
    // Traverse distinct characters
    // of left subString
    for (char v : ls) {
 
        // If current character is
        // present in right subString
        if (rs.contains(v)) {
 
            // Update cnt
            ++cnt;
        }
    }
 
    // Return count
    return cnt;
}
 
// Function to partition the String into
// two non-empty subStrings in all possible ways
static void partitionStringWithMaxCom(String S)
{
    // Stores maximum common distinct characters
    // present in both the subString partitions
    int ans = 0;
 
    // Traverse the String
    for (int i = 1; i < S.length(); ++i) {
 
        // Update ans
        ans = Math.max(ans,
                  countCommonChar(i, S));
    }
 
    // Print count of maximum common
    // non-repeating characters
    System.out.print(ans+ "\n");
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "aabbca";
 
    partitionStringWithMaxCom(str);
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to implement
# the above approach
 
# Function to count maximum common
# non-repeating characters that can
# be obtained by partitioning the
# string into two non-empty substrings
def countCommonChar(ind, S):
     
    # Stores count of non-repeating
    # characters present in both the
    # substrings
    cnt = 0
 
    # Stores distinct characters
    # in left substring
    ls = set()
 
    # Stores distinct characters
    # in right substring
    rs = set()
 
    # Traverse left substring
    for i in range(ind):
         
        # Insert S[i] into ls
        ls.add(S[i])
 
    # Traverse right substring
    for i in range(ind, len(S)):
 
        # Insert S[i] into rs
        rs.add(S[i])
 
    # Traverse distinct characters
    # of left substring
    for v in ls:
 
        # If current character is
        # present in right substring
        if v in rs:
 
            # Update cnt
            cnt += 1
 
    # Return count
    return cnt
 
# Function to partition the string
# into two non-empty substrings in
# all possible ways
def partitionStringWithMaxCom(S):
     
    # Stores maximum common distinct
    # characters present in both the
    # substring partitions
    ans = 0
 
    # Traverse the string
    for i in range(1, len(S)):
 
        # Update ans
        ans = max(ans, countCommonChar(i, S))
 
    # Print count of maximum common
    # non-repeating characters
    print(ans)
 
# Driver Code
if __name__ == "__main__":
 
    string = "aabbca"
 
    partitionStringWithMaxCom(string)
 
# This code is contributed by AnkThon


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the String into two non-empty subStrings
static int countCommonChar(int ind, String S)
{
     
    // Stores count of non-repeating characters
    // present in both the subStrings
    int cnt = 0;
 
    // Stores distinct characters
    // in left subString
    HashSet ls = new HashSet();
 
    // Stores distinct characters
    // in right subString
    HashSet rs = new HashSet();
 
    // Traverse left subString
    for(int i = 0; i < ind; ++i)
    {
         
        // Insert S[i] into ls
        ls.Add(S[i]);
    }
 
    // Traverse right subString
    for(int i = ind; i < S.Length; ++i)
    {
         
        // Insert S[i] into rs
        rs.Add(S[i]);
    }
 
    // Traverse distinct characters
    // of left subString
    foreach(char v in ls)
    {
         
        // If current character is
        // present in right subString
        if (rs.Contains(v))
        {
             
            // Update cnt
            ++cnt;
        }
    }
 
    // Return count
    return cnt;
}
 
// Function to partition the String into
// two non-empty subStrings in all possible ways
static void partitionStringWithMaxCom(String S)
{
     
    // Stores maximum common distinct characters
    // present in both the subString partitions
    int ans = 0;
 
    // Traverse the String
    for(int i = 1; i < S.Length; ++i)
    {
         
        // Update ans
        ans = Math.Max(ans,
                       countCommonChar(i, S));
    }
 
    // Print count of maximum common
    // non-repeating characters
    Console.Write(ans + "\n");
}
 
// Driver Code
public static void Main(String[] args)
{
    String str = "aabbca";
 
    partitionStringWithMaxCom(str);
}
}
 
// This code is contributed by Amit Katiyar


C++
// C++ program to implement
// the above approach
 
#include 
#include 
#include 
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
template 
using ordered_set = tree,
                         rb_tree_tag, tree_order_statistics_node_update>;
 
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the string into two non-empty substrings
int countMaxCommonChar(string& S)
{
    // Stores distinct characters
    // of S in sorted order
    ordered_set Q;
 
    // Stores maximum common distinct characters
    // present in both the partitions
    int res = 0;
 
    // Stores frequency of each
    // distinct character n the string S
    map freq;
 
    // Traverse the string
    for (int i = 0; i < S.length(); i++) {
 
        // Update frequency of S[i]
        freq[S[i]]++;
    }
 
    // Traverse the string
    for (int i = 0; i < S.length(); i++) {
 
        // Decreasing frequency of S[i]
        freq[S[i]]--;
 
        // If the frequency of S[i] is 0
        if (!freq[S[i]]) {
 
            // Remove S[i] from Q
            Q.erase(S[i]);
        }
        else {
 
            // Insert S[i] into Q
            Q.insert(S[i]);
        }
 
        // Stores count of distinct
        // characters in Q
        int curr = Q.size();
 
        // Update res
        res = max(res, curr);
    }
 
    cout << res << "\n";
}
 
// Driver Code
int main()
{
    string str = "aabbca";
 
    // Function call
    countMaxCommonChar(str);
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
     
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the String into two non-empty subStrings
static void countMaxCommonChar(char[] S)
{
     
    // Stores distinct characters
    // of S in sorted order
    LinkedHashSet Q = new LinkedHashSet<>();
 
    // Stores maximum common distinct characters
    // present in both the partitions
    int res = 1;
 
    // Stores frequency of each
    // distinct character n the String S
    HashMap freq = new HashMap<>();
 
    // Traverse the String
    for(int i = 0; i < S.length; i++)
    {
         
        // Update frequency of S[i]
        if (freq.containsKey(S[i]))
        {
            freq.put(S[i], freq.get(S[i]) + 1);
        }
        else
        {
            freq.put(S[i], 1);
        }
    }
 
    // Traverse the String
    for(int i = 0; i < S.length; i++)
    {
         
        // Decreasing frequency of S[i]
        if (freq.containsKey(S[i]))
        {
            freq.put(S[i], freq.get(S[i]) - 1);
        }
 
        // If the frequency of S[i] is 0
        if (!freq.containsKey(S[i]))
        {
             
            // Remove S[i] from Q
            Q.remove(S[i]);
        }
        else
        {
             
            // Insert S[i] into Q
            Q.add(S[i]);
        }
 
        // Stores count of distinct
        // characters in Q
        int curr = Q.size() - 1;
 
        // Update res
        res = Math.max(res, curr);
    }
 
    System.out.print(res + "\n");
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "aabbca";
     
    // Function call
    countMaxCommonChar(str.toCharArray());
}
}
 
// This code is contributed by aashish1995


输出
2

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

高效的方法:为了优化上述方法,其思想是使用“哈希和有序集”以排序顺序存储字符串的不同字符。请按照以下步骤解决问题:

  • 初始化变量,例如res ,以通过将字符串分成两个子字符串来存储两个子字符串存在的常见不同字符的最大数量。
  • 初始化一个映射,例如mp ,以存储字符串的每个不同字符的频率。
  • 初始化一个有序集,例如Q ,以按排序顺序存储字符串的不同字符。
  • 遍历该字符串的字符和为每个i字符,递减str的频率[i]和检查,如果熔点[STR [1]的频率等于0。如果发现为假,则从有序集中删除str [i]
  • 否则,在有序集合中插入str [i]并更新res = max(res,X) ,其中X是有序集合中元素的计数。
  • 最后,打印res的值。

下面是上述方法的实现:

C++

// C++ program to implement
// the above approach
 
#include 
#include 
#include 
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
template 
using ordered_set = tree,
                         rb_tree_tag, tree_order_statistics_node_update>;
 
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the string into two non-empty substrings
int countMaxCommonChar(string& S)
{
    // Stores distinct characters
    // of S in sorted order
    ordered_set Q;
 
    // Stores maximum common distinct characters
    // present in both the partitions
    int res = 0;
 
    // Stores frequency of each
    // distinct character n the string S
    map freq;
 
    // Traverse the string
    for (int i = 0; i < S.length(); i++) {
 
        // Update frequency of S[i]
        freq[S[i]]++;
    }
 
    // Traverse the string
    for (int i = 0; i < S.length(); i++) {
 
        // Decreasing frequency of S[i]
        freq[S[i]]--;
 
        // If the frequency of S[i] is 0
        if (!freq[S[i]]) {
 
            // Remove S[i] from Q
            Q.erase(S[i]);
        }
        else {
 
            // Insert S[i] into Q
            Q.insert(S[i]);
        }
 
        // Stores count of distinct
        // characters in Q
        int curr = Q.size();
 
        // Update res
        res = max(res, curr);
    }
 
    cout << res << "\n";
}
 
// Driver Code
int main()
{
    string str = "aabbca";
 
    // Function call
    countMaxCommonChar(str);
    return 0;
}

Java

// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
     
// Function to count maximum common non-repeating
// characters that can be obtained by partitioning
// the String into two non-empty subStrings
static void countMaxCommonChar(char[] S)
{
     
    // Stores distinct characters
    // of S in sorted order
    LinkedHashSet Q = new LinkedHashSet<>();
 
    // Stores maximum common distinct characters
    // present in both the partitions
    int res = 1;
 
    // Stores frequency of each
    // distinct character n the String S
    HashMap freq = new HashMap<>();
 
    // Traverse the String
    for(int i = 0; i < S.length; i++)
    {
         
        // Update frequency of S[i]
        if (freq.containsKey(S[i]))
        {
            freq.put(S[i], freq.get(S[i]) + 1);
        }
        else
        {
            freq.put(S[i], 1);
        }
    }
 
    // Traverse the String
    for(int i = 0; i < S.length; i++)
    {
         
        // Decreasing frequency of S[i]
        if (freq.containsKey(S[i]))
        {
            freq.put(S[i], freq.get(S[i]) - 1);
        }
 
        // If the frequency of S[i] is 0
        if (!freq.containsKey(S[i]))
        {
             
            // Remove S[i] from Q
            Q.remove(S[i]);
        }
        else
        {
             
            // Insert S[i] into Q
            Q.add(S[i]);
        }
 
        // Stores count of distinct
        // characters in Q
        int curr = Q.size() - 1;
 
        // Update res
        res = Math.max(res, curr);
    }
 
    System.out.print(res + "\n");
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "aabbca";
     
    // Function call
    countMaxCommonChar(str.toCharArray());
}
}
 
// This code is contributed by aashish1995
输出
2

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