给定一个由N个小写字符组成的字符串S ,任务是找到给定字符串S的子字符串的起始和结束索引(基于 0 的索引),需要将其反转以使字符串S排序。如果无法通过反转任何子字符串对给定字符串S进行排序,则打印“-1” 。
例子:
Input: S = “abcyxuz”
Output: 3 5
Explanation: Reversing the substring from indices [3, 5] modifies the string to “abcuxyz”, which is sorted.
Therefore, print 3 and 5.
Input: S = “GFG”
Output: 0 1
朴素的方法:解决给定问题的最简单方法是生成给定字符串S 的所有可能子字符串,如果存在任何子字符串,则将字符串进行排序,然后打印该子字符串的索引。否则,打印“-1” 。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效的方法:上述方法也可以根据观察进行优化,即仅通过反转一个子字符串来对字符串进行排序,原始字符串必须采用以下格式之一:
- 递减字符串
- 增加子串+减少子串
- 减少子串+增加子串
- 增加子串+减少子串+增加子串
请按照以下步骤解决问题:
- 初始化两个变量,比如start和end为-1 ,它们分别存储要反转的子字符串的开始和结束索引。
- 初始化一个变量,比如flag为1 ,它存储是否可以对字符串进行排序。
- 迭代范围[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,则将start和end的值更新为1 。
- 完成上述步骤后,打印start和end的值作为结果。
下面是上述方法的实现:
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