Open In App

Sequence Transformation by Cyclic Shifting

Last Updated : 03 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two arrays of positive integers A[] and B[], both of length N, the task is to determine whether it is possible to transform sequence A into sequence B by repeating the following operation any number of times: Choose an index i (1 ≤ i ≤ N) and replace A[i] with A[i+1]. If i = N, replace A[N] with A[1]. If transformation is possible then print “YES” or else “NO”.

Examples:

Input: N = 4, A = [1, 1, 2, 3] , B = [1, 2, 2, 1]
Output: YES

Input: N = 4, A = [1, 2, 3, 4], B = [2, 3, 4, 1]
Output: NO

Approach: We can follow the below idea to solve this problem:

In this approach, We create modified sequences without consecutive equal elements and checks if these modified sequences can be transformed into each other using cyclic shifts.

Here is the step-by-step algorithm of this code:

  • Start by defining two input sequences, A and B, with size N.
  • If A is already equal to B, output “YES” and terminate the program.
  • Check if either A or B contains consecutive equal elements (like A[i] == A[i+1] or B[i] == B[i+1]) or not. If they do not, then it is not possible to transform A into B. In this case, output “NO” and terminate the program.
  • Create new sequences, modifiedA, and modifiedB, without consecutive equal elements by removing duplicates.
  • If modifiedA is empty, select the first element of A as the only element in modifiedA.
  • If modifiedB is empty, select the first element of B as the only element in modifiedB.
  • Check if modifiedA can transform into modifiedB by cyclically shifting modifiedA and comparing it with modifiedB.
    • Iterate over all possible starting positions of modifiedA.
    • For each starting position, check if the elements of modifiedA match the elements of modifiedB.
    • If all elements of modifiedB are found in modifiedA, output “YES” and terminate the program.
  • If no match is found in step 7, output “NO” to indicate that it is not possible to transform A into B.

Below is the implementation of the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if sequence v can
// transform into sequence w
bool Check(vector<int>& v, vector<int>& w)
{
    int L = v.size();
    int R = w.size();
 
    // Duplicate sequence v to handle
    // cyclic shifts
    for (int i = 0; i < L; i++) {
        v.push_back(v[i]);
    }
 
    // Iterate over all possible starting
    // positions of v
    for (int i = 0; i < L; i++) {
        int p = 0;
 
        // Check if the elements of v
        // match the elements of w
        for (int j = 0; j < L; j++) {
            if (v[i + j] == w[p]) {
                p++;
            }
 
            // If all elements of w are
            // found in v, return true
            if (p == R)
                return true;
        }
    }
 
    // If no match is found,
    // return false
    return false;
}
 
// Drivers code
int main()
{
    int N = 4;
 
    // Sample input sequences A and B
    vector<int> A = { 1, 1, 2, 3 };
    vector<int> B = { 1, 2, 2, 1 };
 
    // If A is already equal to B, print
    // "YES" and return
    if (A == B) {
        cout << "YES" << endl;
        return 0;
    }
 
    bool ed = true;
 
    // Check if A or B contains
    // consecutive equal elements
    for (int i = 0; i < N; i++) {
        if (A[i] == A[(i + 1) % N]) {
            ed = false;
        }
        if (B[i] == B[(i + 1) % N]) {
            ed = false;
        }
    }
 
    // If both A and B have consecutive
    // equal elements, it is not possible
    // to transform A into B
    if (ed) {
        cout << "NO" << endl;
        return 0;
    }
 
    vector<int> modifiedA;
    vector<int> modifiedB;
 
    // Create new sequences without
    // consecutive equal elements
    for (int i = 0; i < N; i++) {
        if (A[i] != A[(i + 1) % N]) {
            modifiedA.push_back(A[i]);
        }
        if (B[i] != B[(i + 1) % N]) {
            modifiedB.push_back(B[i]);
        }
    }
 
    // If modified sequences are empty,
    // select the first element of A and
    // B as the only element
    if (modifiedA.empty()) {
        modifiedA.push_back(A[0]);
    }
    if (modifiedB.empty()) {
        modifiedB.push_back(B[0]);
    }
 
    // Check if modified sequences can
    // transform A into B
    if (Check(modifiedA, modifiedB)) {
        cout << "YES" << endl;
    }
    else {
        cout << "NO" << endl;
    }
 
    return 0;
}


Java




import java.util.ArrayList;
 
public class Main {
     
    // Function to check if sequence v can transform into sequence w
    public static boolean check(ArrayList<Integer> v, ArrayList<Integer> w) {
        int L = v.size();
        int R = w.size();
 
        // Duplicate sequence v to handle cyclic shifts
        for (int i = 0; i < L; i++) {
            v.add(v.get(i));
        }
 
        // Iterate over all possible starting positions of v
        for (int i = 0; i < L; i++) {
            int p = 0;
 
            // Check if the elements of v match the elements of w
            for (int j = 0; j < L; j++) {
                if (v.get(i + j).equals(w.get(p))) {
                    p++;
                }
 
                // If all elements of w are found in v, return true
                if (p == R)
                    return true;
            }
        }
 
        // If no match is found, return false
        return false;
    }
 
    // Main function
    public static void main(String[] args) {
        int N = 4;
 
        // Sample input sequences A and B
        ArrayList<Integer> A = new ArrayList<>();
        A.add(1);
        A.add(1);
        A.add(2);
        A.add(3);
 
        ArrayList<Integer> B = new ArrayList<>();
        B.add(1);
        B.add(2);
        B.add(2);
        B.add(1);
 
        // If A is already equal to B, print "YES" and return
        if (A.equals(B)) {
            System.out.println("YES");
            return;
        }
 
        boolean ed = true;
 
        // Check if A or B contains consecutive equal elements
        for (int i = 0; i < N; i++) {
            if (A.get(i).equals(A.get((i + 1) % N))) {
                ed = false;
            }
            if (B.get(i).equals(B.get((i + 1) % N))) {
                ed = false;
            }
        }
 
        // If both A and B have consecutive equal elements,
        // it is not possible to transform A into B
        if (ed) {
            System.out.println("NO");
            return;
        }
 
        ArrayList<Integer> modifiedA = new ArrayList<>();
        ArrayList<Integer> modifiedB = new ArrayList<>();
 
        // Create new sequences without consecutive equal elements
        for (int i = 0; i < N; i++) {
            if (!A.get(i).equals(A.get((i + 1) % N))) {
                modifiedA.add(A.get(i));
            }
            if (!B.get(i).equals(B.get((i + 1) % N))) {
                modifiedB.add(B.get(i));
            }
        }
 
        // If modified sequences are empty, select the first element
        // of A and B as the only element
        if (modifiedA.isEmpty()) {
            modifiedA.add(A.get(0));
        }
        if (modifiedB.isEmpty()) {
            modifiedB.add(B.get(0));
        }
 
        // Check if modified sequences can transform A into B
        if (check(modifiedA, modifiedB)) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
}
//Contributed by Aditi Tyagi


Python3




def check(v, w):
    L = len(v)
    R = len(w)
 
    # Duplicate sequence v to handle cyclic shifts
    v = v + v
 
    # Iterate over all possible starting positions of v
    for i in range(L):
        p = 0
 
        # Check if the elements of v match the elements of w
        for j in range(L):
            if v[i + j] == w[p]:
                p += 1
 
            # If all elements of w are found in v, return true
            if p == R:
                return True
 
    # If no match is found, return false
    return False
 
if __name__ == "__main__":
    N = 4
 
    # Sample input sequences A and B
    A = [1, 1, 2, 3]
    B = [1, 2, 2, 1]
 
    # If A is already equal to B, print "YES" and return
    if A == B:
        print("YES")
        exit(0)
 
    ed = True
 
    # Check if A or B contains consecutive equal elements
    for i in range(N):
        if A[i] == A[(i + 1) % N]:
            ed = False
        if B[i] == B[(i + 1) % N]:
            ed = False
 
    # If both A and B have consecutive equal elements, it is not possible to transform A into B
    if ed:
        print("NO")
        exit(0)
 
    modifiedA = []
    modifiedB = []
 
    # Create new sequences without consecutive equal elements
    for i in range(N):
        if A[i] != A[(i + 1) % N]:
            modifiedA.append(A[i])
        if B[i] != B[(i + 1) % N]:
            modifiedB.append(B[i])
 
    # If modified sequences are empty, select the first element of A and B as the only element
    if not modifiedA:
        modifiedA.append(A[0])
    if not modifiedB:
        modifiedB.append(B[0])
 
    # Check if modified sequences can transform A into B
    if check(modifiedA, modifiedB):
        print("YES")
    else:
        print("NO")


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // Function to check if sequence v can
    // transform into sequence w
    static bool Check(List<int> v, List<int> w)
    {
        int L = v.Count;
        int R = w.Count;
 
        // Duplicate sequence v to handle
        // cyclic shifts
        for (int i = 0; i < L; i++)
        {
            v.Add(v[i]);
        }
 
        // Iterate over all possible starting
        // positions of v
        for (int i = 0; i < L; i++)
        {
            int p = 0;
 
            // Check if the elements of v
            // match the elements of w
            for (int j = 0; j < L; j++)
            {
                if (v[i + j] == w[p])
                {
                    p++;
                }
 
                // If all elements of w are
                // found in v, return true
                if (p == R)
                    return true;
            }
        }
 
        // If no match is found,
        // return false
        return false;
    }
 
    // Main method
    static void Main()
    {
        int N = 4;
 
        // Sample input sequences A and B
        List<int> A = new List<int> { 1, 1, 2, 3 };
        List<int> B = new List<int> { 1, 2, 2, 1 };
 
        // If A is already equal to B, print
        // "YES" and return
        if (A.Count == B.Count)
        {
            bool areEqual = true;
            for (int i = 0; i < N; i++)
            {
                if (A[i] != B[i])
                {
                    areEqual = false;
                    break;
                }
            }
 
            if (areEqual)
            {
                Console.WriteLine("YES");
                return;
            }
        }
 
        bool ed = true;
 
        // Check if A or B contains
        // consecutive equal elements
        for (int i = 0; i < N; i++)
        {
            if (A[i] == A[(i + 1) % N])
            {
                ed = false;
            }
            if (B[i] == B[(i + 1) % N])
            {
                ed = false;
            }
        }
 
        // If both A and B have consecutive
        // equal elements, it is not possible
        // to transform A into B
        if (ed)
        {
            Console.WriteLine("NO");
            return;
        }
 
        List<int> modifiedA = new List<int>();
        List<int> modifiedB = new List<int>();
 
        // Create new sequences without
        // consecutive equal elements
        for (int i = 0; i < N; i++)
        {
            if (A[i] != A[(i + 1) % N])
            {
                modifiedA.Add(A[i]);
            }
            if (B[i] != B[(i + 1) % N])
            {
                modifiedB.Add(B[i]);
            }
        }
 
        // If modified sequences are empty,
        // select the first element of A and
        // B as the only element
        if (modifiedA.Count == 0)
        {
            modifiedA.Add(A[0]);
        }
        if (modifiedB.Count == 0)
        {
            modifiedB.Add(B[0]);
        }
 
        // Check if modified sequences can
        // transform A into B
        if (Check(modifiedA, modifiedB))
        {
            Console.WriteLine("YES");
        }
        else
        {
            Console.WriteLine("NO");
        }
    }
}


Javascript




// Function to check if sequence v can
// transform into sequence w
function Check(v, w) {
    const L = v.length;
    const R = w.length;
 
    // Duplicate sequence v to handle
    // cyclic shifts
    for (let i = 0; i < L; i++) {
        v.push(v[i]);
    }
 
    // Iterate over all possible starting
    // positions of v
    for (let i = 0; i < L; i++) {
        let p = 0;
 
        // Check if the elements of v
        // match the elements of w
        for (let j = 0; j < L; j++) {
            if (v[i + j] === w[p]) {
                p++;
            }
 
            // If all elements of w are
            // found in v, return true
            if (p === R) {
                return true;
            }
        }
    }
 
    // If no match is found,
    // return false
    return false;
}
 
// Main function
function main() {
    const N = 4;
 
    // Sample input sequences A and B
    const A = [1, 1, 2, 3];
    const B = [1, 2, 2, 1];
 
    // If A is already equal to B, print
    // "YES" and return
    if (A.length === B.length) {
        let areEqual = true;
        for (let i = 0; i < N; i++) {
            if (A[i] !== B[i]) {
                areEqual = false;
                break;
            }
        }
 
        if (areEqual) {
            console.log("YES");
            return;
        }
    }
 
    let ed = true;
 
    // Check if A or B contains
    // consecutive equal elements
    for (let i = 0; i < N; i++) {
        if (A[i] === A[(i + 1) % N]) {
            ed = false;
        }
        if (B[i] === B[(i + 1) % N]) {
            ed = false;
        }
    }
 
    // If both A and B have consecutive
    // equal elements, it is not possible
    // to transform A into B
    if (ed) {
        console.log("NO");
        return;
    }
 
    const modifiedA = [];
    const modifiedB = [];
 
    // Create new sequences without
    // consecutive equal elements
    for (let i = 0; i < N; i++) {
        if (A[i] !== A[(i + 1) % N]) {
            modifiedA.push(A[i]);
        }
        if (B[i] !== B[(i + 1) % N]) {
            modifiedB.push(B[i]);
        }
    }
 
    // If modified sequences are empty,
    // select the first element of A and
    // B as the only element
    if (modifiedA.length === 0) {
        modifiedA.push(A[0]);
    }
    if (modifiedB.length === 0) {
        modifiedB.push(B[0]);
    }
 
    // Check if modified sequences can
    // transform A into B
    if (Check(modifiedA, modifiedB)) {
        console.log("YES");
    } else {
        console.log("NO");
    }
}
 
// Call the main function
main();


Output

YES








Time Complexity: O(N2)

Space Complexity: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads