找到没有重复字符的给定字符串的后缀数组
给定一个大小为N的字符串str ,任务是找到给定字符串的后缀数组。
注意:后缀数组是给定字符串的所有后缀的排序数组。
例子:
Input: str = “prince”
Output: 4 5 2 3 0 1
Explanation: The suffixes are
0 prince 4 ce
1 rince Sort the suffixes 5 e
2 ince —————-> 2 ince
3 nce alphabetically 3 nce
4 ce 0 prince
5 e 1 rince
Input: str = “abcd”
Output: 0 1 2 3
方法:这里讨论任何字符串的后缀数组查找方法。在本文中,重点是为没有重复字符的字符串查找后缀数组。这是一个简单的基于实现的问题。请按照以下步骤解决问题:
- 计算每个字符的出现次数。
- 找到它的前缀和。
- 通过 start[0] = 0, start[i+1] = prefix[i] 查找所有 i > 0 的起始数组。
- 查找包含子字符串(后缀)索引的起始数组,其中包含相应列的起始字符。
请按照下图更好地理解。
插图:
Consider string “prince”:
Given below is the suffix table char a b c d e f g h i j k l m n o p q r s t u v w x y z count 0 0 1 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 prefix 0 0 1 1 2 2 2 2 3 3 3 3 3 4 4 5 5 6 6 6 6 6 6 6 6 6 start 0 0 0 1 1 2 2 2 2 3 3 3 3 3 4 4 5 5 6 6 6 6 6 6 6 6
For char ‘r’ start value is 5 .
Implies substring (suffix) starting with char ‘r’ i.e. “rince” has rank 5 .
Rank is position in suffix array. ( 1 “rince” ) implies 5th position in suffix array ), refer first table.
Similarly, start value of char ‘n’ is 3 . Implies ( 3 “nce” ) 3rd position in suffix array .
下面是上述方法的实现
C++
// C++ code to implement above approach
#include
using namespace std;
// Function to calculate the suffix array
void suffixArray(string str, int N)
{
// arr[] is array to count
// occurrence of each character
int arr[30] = { 0 };
for (int i = 0; i < N; i++) {
arr[str[i] - 'a']++;
}
// Finding prefix count of character
for (int i = 1; i < 30; i++) {
arr[i] = arr[i] + arr[i - 1];
}
int start[30];
start[0] = 0;
for (int i = 0; i < 29; i++) {
start[i + 1] = arr[i];
}
int ans[N] = { 0 };
// Iterating string in reverse order
for (int i = N - 1; i >= 0; i--) {
// Storing suffix array in ans[]
ans[start[str[i] - 'a']] = i;
}
for (int i = 0; i < N; i++)
cout << ans[i] << " ";
}
// Driver code
int main()
{
string str = "prince";
int N = str.length();
suffixArray(str, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
// Function to calculate the suffix array
static void suffixArray(String str, int N)
{
// arr[] is array to count
// occurrence of each character
int arr[] = new int[30];
for (int i = 0; i < N; i++) {
arr[str.charAt(i) - 'a']++;
}
// Finding prefix count of character
for (int i = 1; i < 30; i++) {
arr[i] = arr[i] + arr[i - 1];
}
int start[] = new int[30];
start[0] = 0;
for (int i = 0; i < 29; i++) {
start[i + 1] = arr[i];
}
int ans[] = new int[N];
// Iterating string in reverse order
for (int i = N - 1; i >= 0; i--) {
// Storing suffix array in ans[]
ans[start[str.charAt(i) - 'a']] = i;
}
for (int i = 0; i < N; i++)
System.out.print(ans[i] + " ");
}
// Driver code
public static void main (String[] args)
{
String str = "prince";
int N = str.length();
suffixArray(str, N);
}
}
// This code is contributed by hrithikgarg03188
Python3
# Python code for the above approach
# Function to calculate the suffix array
def suffixArray(str, N):
# arr[] is array to count
# occurrence of each character
arr = [0] * 30
for i in range(N):
arr[ord(str[i]) - ord('a')] += 1
# Finding prefix count of character
for i in range(1, 30):
arr[i] = arr[i] + arr[i - 1]
start = [0] * 30
start[0] = 0
for i in range(29):
start[i + 1] = arr[i]
ans = [0] * N
# Iterating string in reverse order
for i in range(N - 1, 0, -1):
# Storing suffix array in ans[]
ans[start[ord(str[i]) - ord('a')]] = i
for i in range(N):
print(ans[i], end=" ")
# Driver code
str = "prince"
N = len(str)
suffixArray(str, N)
# This code is contributed by gfgking
C#
// C# code to implement above approach
using System;
class GFG
{
// Function to calculate the suffix array
static void suffixArray(string str, int N)
{
// arr[] is array to count
// occurrence of each character
int[] arr = new int[30];
for (int i = 0; i < N; i++) {
arr[str[i] - 'a']++;
}
// Finding prefix count of character
for (int i = 1; i < 30; i++) {
arr[i] = arr[i] + arr[i - 1];
}
int[] start = new int[30];
start[0] = 0;
for (int i = 0; i < 29; i++) {
start[i + 1] = arr[i];
}
int[] ans = new int[N];
// Iterating string in reverse order
for (int i = N - 1; i >= 0; i--) {
// Storing suffix array in ans[]
ans[start[str[i] - 'a']] = i;
}
for (int i = 0; i < N; i++) {
Console.Write(ans[i]);
Console.Write(" ");
}
}
// Driver code
public static int Main()
{
string str = "prince";
int N = str.Length;
suffixArray(str, N);
return 0;
}
}
// This code is contributed by Taranpreet
Javascript
4 5 2 3 0 1
时间复杂度: O(N)
辅助空间: O(N)