📌  相关文章
📜  通过交换给定字符或水平旋转 Q 查询来翻转字符串

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

通过交换给定字符或水平旋转 Q 查询来翻转字符串

给定一个长度为2N的字符串SQ 查询,每个查询包含三个整数TAB ,其中查询可以是以下两种类型:

  • T=1:交换S中的AthBth字符。(在基于 1 的索引中)
  • T=2:将前N个字符与后N个字符交换,即“ABCD”变为“CDAB”

任务是在对其应用Q 查询之后找到最终的字符串。

例子:

天真的方法:按照以下步骤解决问题:

  1. 遍历Queries数组,对于每个当前索引i ,执行以下操作:
    1. TAB提取为T=Q[i][0]、A=Q[i][1]B=Q[i][2]。
    2. 递减AB以使它们从 0 索引。
    3. 如果T等于1 ,则分别交换索引AB处的字符。
    4. 否则,将字符串从0遍历到N-1 ,并将每个A[j]A[j+N] 交换。
  2. 打印字符串S

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find final string
// after applying all Queries on it
void solve(string S, int N,
           vector > Queries,
           int Q)
{
    // Traverse the Queries array
    for (int i = 0; i < Q; i++) {
        int T = Queries[i][0], A = Queries[i][1],
            B = Queries[i][2];
        // convert A, B to zero indexing
        A--;
        B--;
        // Query of 1st type
        if (T == 1) {
            // swap ath and bth characters
            swap(S[A], S[B]);
        }
        // Query of 2nd type
        else {
            // swap first N characters
            // with last N characters
            for (int j = 0; j < N; j++) {
                swap(S[j], S[j + N]);
            }
        }
    }
    // Print answer
    cout << S << endl;
}
// Driver code
int main()
{
    // Input
    string S = "ABCD";
    int N = S.length() / 2;
    vector > Queries
        = { { 2, 0, 0 }, { 1, 1, 3 }, { 2, 0, 0 } };
    int Q = Queries.size();
 
    // Function call
    solve(S, N, Queries, Q);
 
    return 0;
}


Python3
# Python3 program for the above approach
 
# Function to find final string
# after applying all Queries on it
def solve(S, N, Queries, Q):
     
    # Traverse the Queries array
    S = list(S)
    for i in range(Q):
        T = Queries[i][0]
        A = Queries[i][1]
        B = Queries[i][2]
         
        # Convert A, B to zero indexing
        A -= 1
        B -= 1
         
        # Query of 1st type
        if (T == 1):
             
            # Swap ath and bth characters
            temp = S[A]
            S[A] = S[B]
            S[B] = temp
 
        # Query of 2nd type
        else:
             
            # Swap first N characters
            # with last N characters
            for j in range(N):
                temp = S[j]
                S[j] = S[j + N]
                S[j + N] = temp
             
    S = ''.join(S)
             
    # Print answer
    print(S)
     
# Driver code
if __name__ == '__main__':
     
    # Input
    S = "ABCD"
    N = len(S) // 2
    Queries = [ [ 2, 0, 0 ],
                [ 1, 1, 3 ],
                [ 2, 0, 0 ] ]
    Q = len(Queries)
 
    # Function call
    solve(S, N, Queries, Q)
     
# This code is contributed by ipg2016107


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find final string
// after applying all Queries on it
void solve(string S, int N,
           vector > Queries,
           int Q)
{
    int flip = 0;
    // Traverse the Queries array
    for (int i = 0; i < Q; i++) {
        int T = Queries[i][0], A = Queries[i][1],
            B = Queries[i][2];
        // convert A, B to zero indexing
        A--;
        B--;
        // Query of 1st type
        if (T == 1) {
            // simply swap the character at
            // Ath and Bth index
            if (flip % 2 == 0)
                swap(S[A], S[B]);
            else {
                // add N to A, B as string starts at nth
                // index(0 indexing) and take mod with size
                // of string (2*N) and swap the character at
                // Ath and Bth index calculated.
                A = (A + N) % (2 * N);
                B = (B + N) % (2 * N);
                swap(S[A], S[B]);
            }
        }
        // Query of 2nd type
        else {
            // increment flip
            flip++;
        }
    }
    // Print answer
    if (flip % 2 == 0)
        cout << S << endl;
    else {
        // string starts at Nth index;
        for (int i = N; i < 2 * N; i++)
            cout << S[i];
        for (int i = 0; i < N; i++)
            cout << S[i];
        cout << endl;
    }
}
// Driver code
int main()
{
    // Input
    string S = "ABCD";
    int N = S.length() / 2;
    vector > Queries
        = { { 2, 0, 0 }, { 1, 1, 3 }, { 2, 0, 0 } };
    int Q = Queries.size();
 
    // Function call
    solve(S, N, Queries, Q);
 
    return 0;
}


输出
CBAD

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

有效方法:对于类型 2 的每个查询,实际上不需要将前N个字符与后N个字符交换。这可以在最后通过跟踪在单独变量中完成多少次来完成。请按照以下步骤解决问题:

  1. 将变量flip初始化为0 ,它会跟踪对S执行类型 2 的查询的次数。
  2. 遍历Queries数组,对于每个当前索引i ,执行以下操作:
    1. TAB提取为T=Q[i][0]、A=Q[i][1]B=Q[i][2]。
    2. 递减AB以使它们从 0 索引。
    3. 如果T等于1 ,请执行以下操作:
      1. 检查翻转是否均匀。如果是,只需交换S中的AthBth字符
      2. 否则,相应地更新AB的值(当字符串被翻转时),将N添加到它们,然后用2N取它们的模数。然后交换S中的AthBth字符。
    4. 否则,递增翻转
  3. 检查翻转是否均匀。如果是,则按原样打印S。
  4. 否则, S被翻转,因此先打印S的最后N个字符,然后打印S的前N个字符。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function to find final string
// after applying all Queries on it
void solve(string S, int N,
           vector > Queries,
           int Q)
{
    int flip = 0;
    // Traverse the Queries array
    for (int i = 0; i < Q; i++) {
        int T = Queries[i][0], A = Queries[i][1],
            B = Queries[i][2];
        // convert A, B to zero indexing
        A--;
        B--;
        // Query of 1st type
        if (T == 1) {
            // simply swap the character at
            // Ath and Bth index
            if (flip % 2 == 0)
                swap(S[A], S[B]);
            else {
                // add N to A, B as string starts at nth
                // index(0 indexing) and take mod with size
                // of string (2*N) and swap the character at
                // Ath and Bth index calculated.
                A = (A + N) % (2 * N);
                B = (B + N) % (2 * N);
                swap(S[A], S[B]);
            }
        }
        // Query of 2nd type
        else {
            // increment flip
            flip++;
        }
    }
    // Print answer
    if (flip % 2 == 0)
        cout << S << endl;
    else {
        // string starts at Nth index;
        for (int i = N; i < 2 * N; i++)
            cout << S[i];
        for (int i = 0; i < N; i++)
            cout << S[i];
        cout << endl;
    }
}
// Driver code
int main()
{
    // Input
    string S = "ABCD";
    int N = S.length() / 2;
    vector > Queries
        = { { 2, 0, 0 }, { 1, 1, 3 }, { 2, 0, 0 } };
    int Q = Queries.size();
 
    // Function call
    solve(S, N, Queries, Q);
 
    return 0;
}
输出
CBAD

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