📌  相关文章
📜  通过将字符串S 的子串恰好 K 次反转形成的字典上最小的字符串

📅  最后修改于: 2022-05-13 01:56:16.199000             🧑  作者: Mango

通过将字符串S 的子串恰好 K 次反转形成的字典上最小的字符串

给定一个字符串S和一个整数K ,任务是在将任意长度的任何子字符串恰好反转K次后找到字典上可能的最小字符串。

例子:

方法:要在K步中形成按字典顺序最小的字符串,在每一步中选择一个整数L ,其中S[L]是所有字符按排序顺序之前的字符,以及一个整数R ,字符S[R]是必须放置在S[L+1]处,以便S [L+1] 之前的所有字符都按排序顺序排列。在每一步中反转子串S[L..R] ,最终得到所需的字符串。请按照以下步骤解决问题:

  • 让给定的字符串为S ,创建另一个等于S的字符串S1然后按升序对S1进行排序。
  • 该算法需要三个嵌套循环,外层循环会从0运行到K (操作次数)
  • 在每个操作中,搜索两个整数LR ,找到它们后,我们反转子字符串S[L ... R]并继续进行后续操作。
  • 使用两个嵌套循环根据操作数在S中搜索S1的字符。
  • 由于需要在一次操作中只反转一个子字符串,因此只需在S中找到S1的一个字符,即S[R] (在之前的操作中必须放在S的已排序字符之后的字符)并找到S [L] (子字符串S[0…L-1]已排序,因此我们不必对它做任何事情, S[R]将放置在S[L+1] )。
  • K次操作之后,得到字典序上可能最小的字符串。

插图:

下面是上述方法的实现。

C++
// C++ code to implement the approach
#include 
using namespace std;
 
// Function to return the lexicographically
// minimum string after k operations
string findStr(string s, int k)
{
    // Sorted string
    string ss = s;
    sort(ss.begin(), ss.end());
 
    // String after each operation
    string ans = "";
 
    for (int i = 0; i < k; i++) {
        ans = "";
        int r = 0;
        int l = -1;
 
        for (int i = 0; i < s.length(); i++) {
            for (int j = 0; j < ss.length(); j++) {
                if (s[j] == ss[i] && i == j) {
                    l = i;
                    break;
                }
                else if (s[j] == ss[i]) {
                    r = j;
                    break;
                }
            }
            if (r > 0)
 
                // to avoid unnecessary cheking
                break;
        }
 
        // There is no group of sorted characters
        // in the beginning of the string S
        if (l == -1) {
            for (int i = r; i >= 0; i--)
                ans.push_back(s[i]);
            for (int i = r + 1; i < s.length(); i++)
                ans.push_back(s[i]);
        }
        // string S is already sorted or S = SS
        else if (l == s.length() - 1) {
            ans = s;
        }
        // Some part of string S in the beginning
        // is sorted
        else {
            for (int i = 0; i <= l; i++)
                ans.push_back(s[i]);
            for (int i = r; i > l; i--)
                ans.push_back(s[i]);
            for (int i = r + 1; i < s.length(); i++)
                ans.push_back(s[i]);
        }
        // cout << "after " << i+1 << " operations
        // : " << ans << '\n'; use the above line of
        // code to see how S changes after every
        // operation
 
        s = ans;
    }
    return s;
}
 
// Driver Code
int main()
{
    // Number of operations
    int K = 3;
 
    // Given string
    string S = "fgazcbdfge";
 
    // Final answer string
    string ans = findStr(S, K);
    cout << ans;
    return 0;
}


Python3
# python3 code to implement the approach
 
# Function to return the lexicographically
# minimum string after k operations
def findStr(s, k):
 
    # Sorted string
    ss = list(s)
    ss.sort()
 
    # String after each operation
    ans = ""
 
    for i in range(0, k):
        ans = ""
        r = 0
        l = -1
 
        for i in range(0, len(s)):
            for j in range(0, len(ss)):
                if (s[j] == ss[i] and i == j):
                    l = i
                    break
 
                elif (s[j] == ss[i]):
                    r = j
                    break
 
            if (r > 0):
 
                # to avoid unnecessary cheking
                break
 
        # There is no group of sorted characters
        # in the beginning of the string S
        if (l == -1):
            for i in range(r, -1, -1):
                ans += s[i]
            for i in range(r+1, len(s)):
                ans += s[i]
 
        # string S is already sorted or S = SS
        elif (l == len(s) - 1):
            ans = s
 
        # Some part of string S in the beginning
        # is sorted
        else:
            for i in range(0, l+1):
                ans += s[i]
            for i in range(r, l, -1):
                ans += s[i]
            for i in range(r + 1, len(s)):
                ans += s[i]
 
        # print(f"after {i+1} operations: {ans}")
        # use the above line of
        # code to see how S changes after every
        # operation
 
        s = ans
 
    return s
 
# Driver Code
if __name__ == "__main__":
 
    # Number of operations
    K = 3
 
    # Given string
    S = "fgazcbdfge"
 
    # Final answer string
    ans = findStr(S, K)
    print(ans)
 
# This code is contributed by rakeshsahni


C#
// C# code to implement the approach
using System;
class GFG {
 
  // Function to return the lexicographically
  // minimum string after k operations
  static string findStr(string s, int k)
  {
 
    // Sorted string
    string ss = s;
    char[] arr = ss.ToCharArray();
    Array.Sort(arr);
 
    ss = new string(arr);
 
    // String after each operation
    string ans = "";
 
    for (int a = 0; a < k; a++) {
      ans = "";
      int r = 0;
      int l = -1;
 
      for (int i = 0; i < s.Length; i++) {
        for (int j = 0; j < ss.Length; j++) {
          if (s[j] == ss[i] && i == j) {
            l = i;
            break;
          }
          else if (s[j] == ss[i]) {
            r = j;
            break;
          }
        }
        if (r > 0)
 
          // to avoid unnecessary cheking
          break;
      }
 
      // There is no group of sorted characters
      // in the beginning of the string S
      if (l == -1) {
        for (int i = r; i >= 0; i--)
          ans += s[i];
        for (int i = r + 1; i < s.Length; i++)
          ans += s[i];
      }
      // string S is already sorted or S = SS
      else if (l == s.Length - 1) {
        ans = s;
      }
      // Some part of string S in the beginning
      // is sorted
      else {
        for (int i = 0; i <= l; i++)
          ans += s[i];
        for (int i = r; i > l; i--)
          ans += s[i];
        for (int i = r + 1; i < s.Length; i++)
          ans += s[i];
      }
      // cout << "after " << i+1 << " operations
      // : " << ans << '\n'; use the above line of
      // code to see how S changes after every
      // operation
 
      s = ans;
    }
    return s;
  }
 
  // Driver Code
  public static void Main()
  {
 
    // Number of operations
    int K = 3;
 
    // Given string
    string S = "fgazcbdfge";
 
    // Final answer string
    string ans = findStr(S, K);
    Console.Write(ans);
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript



输出
abcdgfzfge

时间复杂度: O(K * N 2 )其中 N 是字符串的长度
辅助空间: O(1)