📜  最长子串的长度,每个字符出现偶数次

📅  最后修改于: 2021-04-24 16:40:15             🧑  作者: Mango

给定长度为N的数字字符串S ,任务是找到每个元素出现偶数次的S最长子字符串的长度。

例子:

天真的方法:最简单的方法是从给定的字符串生成所有可能的偶数长度的子字符串,对于每个子字符串,检查其是否仅包含偶数频率的字符。打印所有此类子字符串中最长的长度。
时间复杂度: O(N 3 )
辅助空间: O(N)

高效的方法:为了优化上述方法,我们的想法是使用位屏蔽。请按照以下步骤解决问题:

  1. 从左到右遍历字符串。
  2. 遍历时,请使用位掩码变量(即mask )来跟踪从索引0到当前索引的每个元素的出现,无论它是偶数还是奇数。第i(0≤I≤9)屏蔽位是0,如果位,如果它已经发生了奇数次已经发生的次数偶数直到当前索引,和1。
  3. 使用变量val来存储当前索引处存在的digit值。
  4. 要更新val的出现,请使用1 << valmask进行按位XOR。
  5. 使用哈希表ind跟踪每个位掩码的索引。
  6. 在当前索引处更新mask的值之后,请检查ind中是否存在该值:
    1. 如果mask的值已经存在于ind中,则意味着从索引ind [mask] +1到当前索引的每个元素均出现偶数次。因此,如果此段从索引ind [mask] +1到当前索引的长度大于答案,则更新答案。
    2. 否则,将当前索引的值分配给ind [mask]
  7. 最后,完成上述步骤后,打印所需子字符串的长度。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find length of the
// longest substring with each element
// occurring even number of times
int lenOfLongestReqSubstr(string s, int N)
{
    // Initialize unordered_map
    unordered_map ind;
 
    int mask = 0;
    ind[0] = -1;
 
    // Stores the length of the
    // longest required substring
    int ans = 0;
 
    // Traverse the string
    for (int i = 0; i < N; i++) {
 
        // Stores the value of the
        // digit present at current index
        int val = s[i] - '0';
 
        // Bitwise XOR of the mask with
        // 1 left-shifted by val
        mask ^= (1 << val);
 
        // Check if the value of mask is
        // already present in ind or not
        if (ind.find(mask) != ind.end()) {
 
            // Update the final answer
            ans = max(ans, i - ind[mask]);
        }
 
        // Otherwise
        else
            ind[mask] = i;
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
int main()
{
    // Given string
    string s = "223015150";
 
    // Length of the given string
    int N = s.length();
 
    // Function Call
    cout << lenOfLongestReqSubstr(s, N);
 
    return 0;
}


Java
// Java program for the
// above approach
import java.util.*;
class GFG{
 
// Function to find length of the
// longest subString with each element
// occurring even number of times
static int lenOfLongestReqSubstr(String s,
                                 int N)
{
  // Initialize unordered_map
  HashMap ind =
          new HashMap<>();
 
  int mask = 0;
  ind.put(0, -1);
 
  // Stores the length of the
  // longest required subString
  int ans = 0;
 
  // Traverse the String
  for (int i = 0; i < N; i++)
  {
    // Stores the value of the
    // digit present at current
    // index
    int val = s.charAt(i) - '0';
 
    // Bitwise XOR of the mask
    // with 1 left-shifted by val
    mask ^= (1 << val);
 
    // Check if the value of mask is
    // already present in ind or not
    if (ind.containsKey(mask))
    {
      // Update the final answer
      ans = Math.max(ans,
                     i - ind.get(mask));
    }
 
    // Otherwise
    else
      ind.put(mask, i);
  }
 
  // Return the answer
  return ans;
}
 
// Driver Code
public static void main(String[] args)
{
  // Given String
  String s = "223015150";
 
  // Length of the given String
  int N = s.length();
 
  // Function Call
  System.out.print(
  lenOfLongestReqSubstr(s, N));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program for the
# above approach
 
# Function to find length of
# the longest substring with
# each element occurring even
# number of times
def lenOfLongestReqSubstr(s, N):
 
    # Initialize unordered_map
    ind = {}
 
    mask = 0
    ind[0] = -1
 
    # Stores the length of the
    # longest required substring
    ans = 0
 
    # Traverse the string
    for i in range(N):
 
        # Stores the value of the
        # digit present at current
        # index
        val = ord(s[i]) - ord('0')
 
        # Bitwise XOR of the mask
        # with 1 left-shifted by val
        mask ^= (1 << val)
 
        # Check if the value of mask
        # is already present in ind
        # or not
        if (mask in ind):
           
            # Update the final answer
            ans = max(ans,
                      i - ind[mask])
 
        # Otherwise
        else:
            ind[mask] = i
 
    # Return the answer
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    # Given string
    s = "223015150"
 
    #:Length of the given
    # string
    N = len(s)
 
    # Function Call
    print(lenOfLongestReqSubstr(s, N))
     
# This code is contributed by Chitranayal


C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to find length of the
// longest subString with each element
// occurring even number of times
static int lenOflongestReqSubstr(String s,
                                 int N)
{
  // Initialize unordered_map
  Dictionary ind =
             new Dictionary();
 
  int mask = 0;
  ind.Add(0, -1);
 
  // Stores the length of the
  // longest required subString
  int ans = 0;
 
  // Traverse the String
  for (int i = 0; i < N; i++)
  {
    // Stores the value of the
    // digit present at current
    // index
    int val = s[i] - '0';
 
    // Bitwise XOR of the mask
    // with 1 left-shifted by val
    mask ^= (1 << val);
 
    // Check if the value of mask is
    // already present in ind or not
    if (ind.ContainsKey(mask))
    {
      // Update the readonly answer
      ans = Math.Max(ans,
                     i - ind[mask]);
    }
 
    // Otherwise
    else
      ind.Add(mask, i);
  }
 
  // Return the answer
  return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given String
  String s = "223015150";
 
  // Length of the given String
  int N = s.Length;
 
  // Function Call
  Console.Write(
  lenOflongestReqSubstr(s, N));
}
}
 
// This code is contributed by 29AjayKumar


输出:
6









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