📌  相关文章
📜  通过反转子字符串按字典顺序对字符串排序

📅  最后修改于: 2021-09-03 03:06:14             🧑  作者: Mango

给定一个由N个小写字符组成的字符串S ,任务是找到给定字符串S的子字符串的起始和结束索引(基于 0 的索引),需要将其反转以使字符串S排序。如果无法通过反转任何子字符串对给定字符串S进行排序,则打印“-1”

例子:

朴素的方法:解决给定问题的最简单方法是生成给定字符串S 的所有可能子字符串,如果存在任何子字符串,则将字符串进行排序,然后打印该子字符串的索引。否则,打印“-1”

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

高效的方法:上述方法也可以根据观察进行优化,即仅通过反转一个子字符串来对字符串进行排序,原始字符串必须采用以下格式之一:

  • 递减字符串
  • 增加子串+减少子串
  • 减少子串+增加子串
  • 增加子串+减少子串+增加子串

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

  • 初始化两个变量,比如startend-1 ,它们分别存储要反转的子字符串的开始和结束索引。
  • 初始化一个变量,比如flag1 ,它存储是否可以对字符串进行排序。
  • 迭代范围[1, N]并执行以下操作:
    • 如果字符S[i]小于字符S[i – 1]则从索引(i – 1)开始找到递减子串的右边界的索引并将其存储在end 中
    • 检查反转子字符串S[i – 1, end] 是否使字符串排序。如果发现为假,则打印“-1”并返回。否则,将标志标记false
    • 完成上述步骤后,用子串的右边界更新i的值。
    • 如果字符S[i]小于字符S[i – 1]并且标志false ,则打印“-1”并返回。
  • 如果start等于-1,则将startend的值更新为1
  • 完成上述步骤后,打印startend的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the substring
// in S required to be reversed
bool adjust(string& S, int& i,
            int& start, int& end)
{
    // Stores the size of the string
    int N = S.length();
 
    // Stores the starting point
    // of the substring
    start = i - 1;
 
    // Iterate over the string S
    // while i < N
    while (i < N && S[i] < S[i - 1]) {
 
        // Increment the value of i
        i++;
    }
 
    // Stores the ending index of
    // the substring
    end = i - 1;
 
    // If start <= 0 or i >= N
    if (start <= 0 && i >= N)
        return true;
 
    // If start >= 1 and i <= N
    if (start >= 1 && i <= N) {
 
        // Return the boolean value
        return (S[end] >= S[start - 1]
                && S[start] <= S[i]);
    }
 
    // If start >= 1
    if (start >= 1) {
 
        // Return the boolean value
        return S[end] >= S[start - 1];
    }
 
    // If i < N
    if (i < N) {
 
        // Return true if S[start]
        // is less than or equal to
        // S[i]
        return S[start] <= S[i];
    }
 
    // Otherwise
    return false;
}
 
// Function to check if it is possible
// to sort the string or not
void isPossible(string& S, int N)
{
    // Stores the starting and the
    // ending index of substring
    int start = -1, end = -1;
 
    // Stores whether it is possible
    // to sort the substring
    bool flag = true;
 
    // Traverse the range [1, N]
    for (int i = 1; i < N; i++) {
 
        // If S[i] is less than S[i-1]
        if (S[i] < S[i - 1]) {
 
            // If flag stores true
            if (flag) {
 
                // If adjust(S, i, start,
                // end) return false
                if (adjust(S, i, start, end)
                    == false) {
 
                    // Print -1
                    cout << -1 << endl;
                    return;
                }
 
                // Unset the flag
                flag = false;
            }
 
            // Otherwise
            else {
 
                // Print -1
                cout << -1 << endl;
                return;
            }
        }
    }
 
    // If start is equal to -1
    if (start == -1) {
        // Update start and end
        start = end = 1;
    }
 
    // Print the value of start
    // and end
    cout << start << " "
         << end << "\n";
}
 
// Driver Code
int main()
{
    string S = "abcyxuz";
    int N = S.length();
    isPossible(S, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
 
class GFG{
     
static int i, start, end;
 
// Function to find the substring
// in S required to be reversed
static boolean adjust(String S)
{
     
    // Stores the size of the string
    int N = S.length();
 
    // Stores the starting point
    // of the substring
    start = i - 1;
 
    // Iterate over the string S
    // while i < N
    while (i < N && S.charAt(i) < 
                    S.charAt(i - 1))
    {
         
        // Increment the value of i
        i++;
    }
 
    // Stores the ending index of
    // the substring
    end = i - 1;
 
    // If start <= 0 or i >= N
    if (start <= 0 && i >= N)
        return true;
 
    // If start >= 1 and i <= N
    if (start >= 1 && i <= N)
    {
         
        // Return the boolean value
        return (S.charAt(end) >= S.charAt(start - 1) &&
                S.charAt(start) <= S.charAt(i));
    }
 
    // If start >= 1
    if (start >= 1)
    {
         
        // Return the boolean value
        return S.charAt(end) >= S.charAt(start - 1);
    }
 
    // If i < N
    if (i < N)
    {
         
        // Return true if S[start]
        // is less than or equal to
        // S[i]
        return S.charAt(start) <= S.charAt(i);
    }
 
    // Otherwise
    return false;
}
 
// Function to check if it is possible
// to sort the string or not
static void isPossible(String S, int N)
{
     
    // Stores the starting and the
    // ending index of substring
    start = -1; end = -1;
 
    // Stores whether it is possible
    // to sort the substring
    boolean flag = true;
 
    // Traverse the range [1, N]
    for(i = 1; i < N; i++)
    {
         
        // If S[i] is less than S[i-1]
        if (S.charAt(i) < S.charAt(i - 1))
        {
             
            // If flag stores true
            if (flag)
            {
                 
                // If adjust(S, i, start,
                // end) return false
                if (adjust(S) == false)
                {
                     
                    // Print -1
                    System.out.println(-1);
                    return;
                }
 
                // Unset the flag
                flag = false;
            }
 
            // Otherwise
            else
            {
                 
                // Print -1
                System.out.println(-1);
                return;
            }
        }
    }
 
    // If start is equal to -1
    if (start == -1)
    {
         
        // Update start and end
        start = end = 1;
    }
 
    // Print the value of start
   System.out.println(start + " " + end);
}
 
// Driver code
public static void main(String[] args)
{
    String S = "abcyxuz";
    int N = S.length();
    isPossible(S, N);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
 
# Function to find the substring
# in S required to be reversed
def adjust(S, i, start, end):
   
    # Stores the size of the string
    N = len(S)
 
    # Stores the starting point
    # of the substring
    start = i - 1
 
    # Iterate over the string S
    # while i < N
    while (i < N and S[i] < S[i - 1]):
         
        # Increment the value of i
        i += 1
 
    # Stores the ending index of
    # the substring
    end = i - 1
 
    # If start <= 0 or i >= N
    if (start <= 0 and i >= N):
        return True,start,i,end
 
    # If start >= 1 and i <= N
    if (start >= 1 and i <= N):
 
        # Return the boolean value
        return (S[end] >= S[start - 1] and S[start] <= S[i]),start,i,end
 
    # If start >= 1
    if (start >= 1):
       
        # Return the boolean value
        return (S[end] >= S[start - 1]),start,i,end
 
    # If i < N
    if (i < N):
 
        # Return true if S[start]
        # is less than or equal to
        # S[i]
        return (S[start] <= S[i]),start,i,end
 
    # Otherwise
    return False,start,i,end
 
# Function to check if it is possible
# to sort the string or not
def isPossible(S, N):
   
    # global start,end,i
    # Stores the starting and the
    # ending index of substring
    start, end = -1, -1
 
    # Stores whether it is possible
    # to sort the substring
    flag = True
 
    # Traverse the range [1, N]
    i = 1
    while i < N:
       
        # If S[i] is less than S[i-1]
        if (S[i] < S[i - 1]):
 
            # If flag stores true
            if (flag):
 
                # If adjust(S, i, start,
                # end) return false
                f, start, i, end = adjust(S, i, start, end)
                if (f== False):
                    # Pr-1
                    print(-1)
                    return
 
                # Unset the flag
                flag = False
            # Otherwise
            else:
 
                # Pr-1
                print(-1)
                return
        i += 1       
 
    # If start is equal to -1
    if (start == -1):
        # Update start and end
        start, end = 1, 1
 
    # Print the value of start
    # and end
    print(start, end)
 
# Driver Code
if __name__ == '__main__':
    S = "abcyxuz"
    N = len(S)
    isPossible(S, N)
 
    # This code is contributed by mohit kumar 29.


C#
// C# program for the above approach
using System;
 
class GFG{
     
static int i, start, end;
 
// Function to find the substring
// in S required to be reversed
static bool adjust(string S)
{
     
    // Stores the size of the string
    int N = S.Length;
 
    // Stores the starting point
    // of the substring
    start = i - 1;
 
    // Iterate over the string S
    // while i < N
    while (i < N && S[i] <  S[i - 1])
    {
         
        // Increment the value of i
        i++;
    }
 
    // Stores the ending index of
    // the substring
    end = i - 1;
 
    // If start <= 0 or i >= N
    if (start <= 0 && i >= N)
        return true;
 
    // If start >= 1 and i <= N
    if (start >= 1 && i <= N)
    {
         
        // Return the boolean value
        return (S[end] >= S[start - 1] &&
                S[start] <= S[i]);
    }
 
    // If start >= 1
    if (start >= 1)
    {
         
        // Return the boolean value
        return S[end] >= S[start - 1];
    }
 
    // If i < N
    if (i < N)
    {
         
        // Return true if S[start]
        // is less than or equal to
        // S[i]
        return S[start] <= S[i];
    }
 
    // Otherwise
    return false;
}
 
// Function to check if it is possible
// to sort the string or not
static void isPossible(string S, int N)
{
     
    // Stores the starting and the
    // ending index of substring
    start = -1; end = -1;
 
    // Stores whether it is possible
    // to sort the substring
    bool flag = true;
 
    // Traverse the range [1, N]
    for(i = 1; i < N; i++)
    {
         
        // If S[i] is less than S[i-1]
        if (S[i] < S[i - 1])
        {
             
            // If flag stores true
            if (flag)
            {
                 
                // If adjust(S, i, start,
                // end) return false
                if (adjust(S) == false)
                {
                     
                    // Print -1
                    Console.WriteLine(-1);
                    return;
                }
 
                // Unset the flag
                flag = false;
            }
 
            // Otherwise
            else
            {
                 
                // Print -1
                 Console.WriteLine(-1);
                return;
            }
        }
    }
 
    // If start is equal to -1
    if (start == -1)
    {
         
        // Update start and end
        start = end = 1;
    }
 
    // Print the value of start
    Console.WriteLine(start + " " + end);
}
 
// Driver code
static void Main()
{
    string S = "abcyxuz";
    int N = S.Length;
     
    isPossible(S, N);
}
}
 
// This code is contributed by SoumikMondal


输出:
3 5

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live