给定n个字符串,我们需要对这些字符串进行排序,以使每个字符串都是其后所有字符串的子字符串。如果无法排序,请打印相同的内容。
例子:
Input : {"d", "zddsaaz", "ds", "ddsaa", "dds"}
Output :
d
ds
dds
ddsaa
zddsaaz
Input : {"geeks", "ee", "geeksforgeeks", "forgeeks", "ee"}
Output :
ee
ee
geeks
forgeeks
geeksforgeeks
观察1
如果A的B子串
那么A的长度<= B的长度
观察2
如果(B的A子串)和(C的B子串)
然后是C的子字符串
解决方案
根据以上两个观察结果,解决方案如下
- 将所有字符串从短到长排序
- 验证每个字符串是以下字符串的子字符串
如果我们验证每个字符串是后续字符串的子字符串,则根据观察2,每个字符串都是其后所有字符串的子字符串。
// Java code to sort substrings
import java.util.Arrays;
import java.util.Comparator;
public class Demo {
public static void substringSort(String[] arr, int n)
{
// sort the given array from shorter string to longer
Arrays.sort(arr, new Comparator() {
public int compare(String s1, String s2)
{
return Integer.compare(s1.length(), s2.length());
}
});
// validate that each string is a substring of
// the following one'
for (int i = 0; i < n - 1; i++) {
if (!arr[i + 1].contains(arr[i])) {
// the array cann't be sorted
System.out.println("Cannot be sorted");
return;
}
}
// The array is valid and sorted
// print the strings in order
for (int i = 0; i < n - 1; i++) {
System.out.println(arr[i]);
}
}
public static void main(String[] args)
{
// Test 1
String[] arr1 = { "d", "zddsaaz", "ds", "ddsaa", "dds" };
substringSort(arr1, arr1.length);
// Test 2
String[] arr2 = { "for", "rof" };
substringSort(arr2, arr2.length);
}
}
输出:
d
ds
dds
ddsaa
Cannot be sorted
复杂
时间复杂度:O(n log n),其中n是字符串。
替代方法
为了提高时间复杂度,仅在指定字符串的最大长度时,才可以使用计数排序。
假设“ maxLen”是输入字符串的最大长度。在这种情况下,解决方案如下:
- 创建长度为maxLen的数组
- 对输入字符串排序,以使长度为1的字符串位于数组的第一位
- 如果有两个或两个以上的字符串具有相同的长度,则它们必须相等,否则无法对字符串进行排序
- 验证每个字符串是否是下一个较长字符串的子字符串
Java
// Alternative code to sort substrings
import java.util.Arrays;
public class Demo {
public static void substringSort(String[] arr, int n, int maxLen)
{
int count[] = new int[maxLen];
String[] sortedArr = new String[maxLen];
Arrays.fill(count, 0);
Arrays.fill(sortedArr, "");
// sort the input array
for (int i = 0; i < n; i++) {
String s = arr[i];
int len = s.length();
if (count[len - 1] == 0) {
sortedArr[len - 1] = s;
count[len - 1] = 1;
}
else if (sortedArr[len - 1].equals(s)) {
// repeated length should be the same string
count[len - 1]++;
}
else {
// two different strings with the same
// length input array cannot be sorted
System.out.println("Cannot be sorted");
return;
}
}
// validate that each string is a substring
// of the following one
int index = 0;
// get first element
while (count[index] == 0)
index++;
int prev = index;
String prevString = sortedArr[prev];
index++;
for (; index < maxLen; index++) {
if (count[index] != 0) {
String current = sortedArr[index];
if (current.contains(prevString)) {
prev = index;
prevString = current;
}
else {
System.out.println("Cannot be sorted");
return;
}
}
}
// The array is valid and sorted
// print the strings in order
for (int i = 0; i < maxLen; i++) {
String s = sortedArr[i];
for (int j = 0; j < count[i]; j++) {
System.out.println(s);
}
}
}
public static void main(String[] args)
{
int maxLen = 100;
// Test 1
String[] arr1 = { "d", "zddsaaz", "ds", "ddsaa",
"dds", "dds" };
substringSort(arr1, arr1.length, maxLen);
// Test 2
String[] arr2 = { "for", "rof" };
substringSort(arr2, arr2.length, maxLen);
}
}
C#
// C# Program to sort substrings
using System;
class GFG
{
public static void substringSort(String[] arr,
int n, int maxLen)
{
int []count = new int[maxLen];
String[] sortedArr = new String[maxLen];
for(int i = 0; i < maxLen; i++)
{
count[i] = 0;
sortedArr[i] = "";
}
// sort the input array
for (int i = 0; i < n; i++)
{
String s = arr[i];
int len = s.Length;
if (count[len - 1] == 0)
{
sortedArr[len - 1] = s;
count[len - 1] = 1;
}
else if (ReferenceEquals(s,sortedArr[len - 1]))
{
// repeated length should
// be the same string
count[len - 1]++;
}
else
{
// two different strings with the same
// length input array cannot be sorted
Console.WriteLine("Cannot be sorted");
return;
}
}
// validate that each string is a
// substring of the following one
int index = 0;
// get first element
while (count[index] == 0)
index++;
int prev = index;
String prevString = sortedArr[prev];
index++;
for (; index < maxLen; index++)
{
if (count[index] != 0)
{
String current = sortedArr[index];
if (current.Contains(prevString))
{
prev = index;
prevString = current;
}
else
{
Console.WriteLine("Cannot be sorted");
return;
}
}
}
// The array is valid and sorted
// print the strings in order
for (int i = 0; i < maxLen; i++)
{
String s = sortedArr[i];
for (int j = 0; j < count[i]; j++)
{
Console.WriteLine(s);
}
}
}
public static void Main(String[] args)
{
int maxLen = 100;
// Test 1
String[] arr1 = { "d", "zddsaaz", "ds", "ddsaa",
"dds", "dds" };
substringSort(arr1, arr1.Length, maxLen);
// Test 2
String[] arr2 = { "for", "rof" };
substringSort(arr2, arr2.Length, maxLen);
}
}
// This code is contributed by PrinciRaj1992
输出:
d
ds
dds
dds
ddsaa
zddsaaz
Cannot be sorted