📌  相关文章
📜  通过用 XOR 替换相邻元素来使数组元素相等

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

通过用 XOR 替换相邻元素来使数组元素相等

给定一个由N个整数组成的数组A[] ,任务是检查是否可以减少至少长度为 2 的数组,使得数组中的所有元素都相等。在一个操作中,选择任何索引 i,并将 A[i] 和 A[i+1] 替换为它们的 XOR 值。

例子:

朴素方法:上述问题可以通过观察给定数组可以简化为具有两个相等元素或三个相等元素的数组来解决。以下是解决上述问题的分步方法:

  • 创建一个前缀数组,其中第i索引存储从索引0到数组A[]i的元素的XOR
  • 案例 1 数组可以简化为两个相等的元素
    • 假设结果数组是{X, X}由于数组中所有元素的 XOR 将保持不变,因此X^X=0=XOR( A[0…N-1]) 。这种情况可以通过检查数组中所有元素的异或是否为0来轻松处理。
  • 案例 2 数组可以简化为三个相等的元素
    • 这种情况可以通过迭代(i, j)的所有可能值来处理,使得0<= i < j <=N-1并检查是否存在(i, j)的值使得XOR(A[ 0…i]) = XOR(A[i+1…j]) = XOR(A[j+1…N])

下面是上述方法的实现:

C++
// C++ Program of the above approach
#include 
using namespace std;
 
// Function to check if it is possible
// to make all the array elements equal
// using the given operation
void possibleEqualArray(int A[], int N)
{
    // Stores the prefix XOR array
    vector pref(N);
    pref[0] = A[0];
 
    for (int i = 1; i < N; i++) {
 
        // Calculate prefix[i]
        pref[i] = pref[i - 1] ^ A[i];
    }
 
    // Case 1, check if the XOR of
    // the input array is 0
    if (pref[N - 1] == 0) {
        cout << "YES";
        return;
    }
 
    // Case 2
    // Iterate over all the ways to
    // divide the array into three
    // non empty subarrays
    int cur_xor = 0;
 
    for (int i = N - 1; i >= 0; i--) {
 
        cur_xor ^= A[i];
 
        for (int j = 0; j < i; j++) {
 
            if (j) {
 
                // XOR of Middle Block
                int middle_xor
 = pref[j - 1] ^ pref[i - 1];
 
                // XOR of Left Block
                int left_xor = pref[j - 1];
 
                // XOR of Right Block
                int right_xor = cur_xor;
 
                if (left_xor == middle_xor
                    && middle_xor == right_xor) {
                    cout << "YES";
                    return;
                }
            }
        }
    }
 
    // Not Possible
    cout << "NO";
}
 
// Driver Code
int main()
{
    int A[] = { 0, 2, 2 };
    int N = sizeof(A) / sizeof(int);
 
    // Function Call
    possibleEqualArray(A, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
 
class GFG
{
 
  // Function to check if it is possible
  // to make all the array elements equal
  // using the given operation
  static void possibleEqualArray(int A[], int N)
  {
 
    // Stores the prefix XOR array
    int[] pref= new int[N];
    pref[0] = A[0];
 
    for (int i = 1; i < N; i++) {
 
      // Calculate prefix[i]
      pref[i] = pref[i - 1] ^ A[i];
    }
 
    // Case 1, check if the XOR of
    // the input array is 0
    if (pref[N - 1] == 0) {
      System.out.println("YES");
      return;
    }
 
    // Case 2
    // Iterate over all the ways to
    // divide the array into three
    // non empty subarrays
    int cur_xor = 0;
 
    for (int i = N - 1; i >= 0; i--) {
 
      cur_xor ^= A[i];
 
      for (int j = 0; j < i; j++) {
 
        if (j!=0) {
 
          // XOR of Middle Block
          int middle_xor
            = pref[j - 1] ^ pref[i - 1];
 
          // XOR of Left Block
          int left_xor = pref[j - 1];
 
          // XOR of Right Block
          int right_xor = cur_xor;
 
          if (left_xor == middle_xor
              && middle_xor == right_xor) {
            System.out.println( "YES");
            return;
          }
        }
      }
    }
 
    // Not Possible
    System.out.println( "NO");
  }
 
  // Driver code
  public static void main (String[] args)
  {
    int A[] = { 0, 2, 2 };
    int N = A.length;
 
    // Function Call
    possibleEqualArray(A, N);
  }
}
 
// This code is contributed by Potta Lokesh


Python3
# Python 3 Program of the above approach
 
# Function to check if it is possible
# to make all the array elements equal
# using the given operation
def possibleEqualArray(A, N):
   
    # Stores the prefix XOR array
    pref = [0 for i in range(N)]
    pref[0] = A[0]
 
    for i in range(1, N, 1):
       
        # Calculate prefix[i]
        pref[i] = pref[i - 1] ^ A[i]
 
    # Case 1, check if the XOR of
    # the input array is 0
    if (pref[N - 1] == 0):
        print("YES")
        return
 
    # Case 2
    # Iterate over all the ways to
    # divide the array into three
    # non empty subarrays
    cur_xor = 0
    i = N - 1
    while(i >= 0):
        cur_xor ^= A[i]
 
        for j in range(i):
            if (j):
                # XOR of Middle Block
                middle_xor = pref[j - 1] ^ pref[i - 1]
 
                # XOR of Left Block
                left_xor = pref[j - 1]
 
                # XOR of Right Block
                right_xor = cur_xor
 
                if (left_xor == middle_xor and middle_xor == right_xor):
                    print("YES")
                    return
 
        i -= 1
 
    # Not Possible
    print("NO")
 
# Driver Code
if __name__ == '__main__':
    A = [0, 2, 2]
    N = len(A)
     
    # Function Call
    possibleEqualArray(A, N)
     
    # This code is contributed by ipg2016107.


C#
// C# program for the above approach
using System;
 
public class GFG
{
 
  // Function to check if it is possible
  // to make all the array elements equal
  // using the given operation
  static void possibleEqualArray(int []A, int N)
  {
 
    // Stores the prefix XOR array
    int[] pref= new int[N];
    pref[0] = A[0];
 
    for (int i = 1; i < N; i++) {
 
      // Calculate prefix[i]
      pref[i] = pref[i - 1] ^ A[i];
    }
 
    // Case 1, check if the XOR of
    // the input array is 0
    if (pref[N - 1] == 0) {
      Console.WriteLine("YES");
      return;
    }
 
    // Case 2
    // Iterate over all the ways to
    // divide the array into three
    // non empty subarrays
    int cur_xor = 0;
 
    for (int i = N - 1; i >= 0; i--) {
 
      cur_xor ^= A[i];
 
      for (int j = 0; j < i; j++) {
 
        if (j!=0) {
 
          // XOR of Middle Block
          int middle_xor
            = pref[j - 1] ^ pref[i - 1];
 
          // XOR of Left Block
          int left_xor = pref[j - 1];
 
          // XOR of Right Block
          int right_xor = cur_xor;
 
          if (left_xor == middle_xor
              && middle_xor == right_xor) {
            Console.WriteLine( "YES");
            return;
          }
        }
      }
    }
 
    // Not Possible
    Console.WriteLine( "NO");
  }
 
  // Driver code
  public static void Main(String[] args)
  {
    int []A = { 0, 2, 2 };
    int N = A.Length;
 
    // Function Call
    possibleEqualArray(A, N);
  }
}
 
// This code is contributed by 29AjayKumar


Javascript


C++
// C++ Program of the above approach
#include 
using namespace std;
 
// Function to check if it is possible
// to make all the array elements equal
// using the given operation
void possibleEqualArray(int A[], int N)
{
    // Stores the XOR of all
    // elements of array A[]
    int tot_XOR = 0;
    for (int i = 0; i < N; i++) {
        tot_XOR ^= A[i];
    }
 
    // Case 1, check if the XOR of
    // the array A[] is 0
    if (tot_XOR == 0) {
        cout << "YES";
        return;
    }
 
    // Case 2
 
    // Maintains the XOR till
    // the current element
    int cur_XOR = 0;
    int cnt = 0;
 
    // Iterate over the array
    for (int i = 0; i < N; i++) {
        cur_XOR ^= A[i];
 
        // If the current XOR is equal
        // to the total XOR increment
        // the count and initialize
        // current XOR as 0
        if (cur_XOR == tot_XOR) {
            cnt++;
            cur_XOR = 0;
        }
    }
 
    // Print Answer
    if (cnt > 2) {
        cout << "YES";
    }
    else {
        cout << "NO";
    }
}
 
// Driver Code
int main()
{
    int A[] = { 0, 2, 2 };
    int N = sizeof(A) / sizeof(int);
 
    // Function Call
    possibleEqualArray(A, N);
 
    return 0;
}


Java
// Java Program of the above approach
import java.util.*;
 
class GFG{
 
// Function to check if it is possible
// to make all the array elements equal
// using the given operation
static void possibleEqualArray(int A[], int N)
{
   
    // Stores the XOR of all
    // elements of array A[]
    int tot_XOR = 0;
    for (int i = 0; i < N; i++) {
        tot_XOR ^= A[i];
    }
 
    // Case 1, check if the XOR of
    // the array A[] is 0
    if (tot_XOR == 0) {
        System.out.print("YES");
        return;
    }
 
    // Case 2
 
    // Maintains the XOR till
    // the current element
    int cur_XOR = 0;
    int cnt = 0;
 
    // Iterate over the array
    for (int i = 0; i < N; i++) {
        cur_XOR ^= A[i];
 
        // If the current XOR is equal
        // to the total XOR increment
        // the count and initialize
        // current XOR as 0
        if (cur_XOR == tot_XOR) {
            cnt++;
            cur_XOR = 0;
        }
    }
 
    // Print Answer
    if (cnt > 2) {
        System.out.print("YES");
    }
    else {
        System.out.print("NO");
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int A[] = { 0, 2, 2 };
    int N =( A.length);
 
    // Function Call
    possibleEqualArray(A, N);
 
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python 3 Program of the above approach
 
# Function to check if it is possible
# to make all the array elements equal
# using the given operation
def possibleEqualArray(A, N):
   
    # Stores the XOR of all
    # elements of array A[]
    tot_XOR = 0
    for i in range(N):
        tot_XOR ^= A[i]
 
    # Case 1, check if the XOR of
    # the array A[] is 0
    if (tot_XOR == 0):
        print("YES")
        return
    # Case 2
 
    # Maintains the XOR till
    # the current element
    cur_XOR = 0
    cnt = 0
 
    # Iterate over the array
    for i in range(N):
        cur_XOR ^= A[i]
 
        # If the current XOR is equal
        # to the total XOR increment
        # the count and initialize
        # current XOR as 0
        if (cur_XOR == tot_XOR):
            cnt += 1
            cur_XOR = 0
 
    # Print Answer
    if (cnt > 2):
        print("YES")
    else:
        print("NO")
 
# Driver Code
if __name__ == '__main__':
    A = [0, 2, 2]
    N = len(A)
 
    # Function Call
    possibleEqualArray(A, N)
     
    # This code is contributed by SURENDRA_GANGWAR.


C#
// C# Program of the above approach
using System;
 
class GFG{
 
// Function to check if it is possible
// to make all the array elements equal
// using the given operation
static void possibleEqualArray(int []A, int N)
{
   
    // Stores the XOR of all
    // elements of array A[]
    int tot_XOR = 0;
    for (int i = 0; i < N; i++) {
        tot_XOR ^= A[i];
    }
 
    // Case 1, check if the XOR of
    // the array A[] is 0
    if (tot_XOR == 0) {
        Console.Write("YES");
        return;
    }
 
    // Case 2
 
    // Maintains the XOR till
    // the current element
    int cur_XOR = 0;
    int cnt = 0;
 
    // Iterate over the array
    for (int i = 0; i < N; i++) {
        cur_XOR ^= A[i];
 
        // If the current XOR is equal
        // to the total XOR increment
        // the count and initialize
        // current XOR as 0
        if (cur_XOR == tot_XOR) {
            cnt++;
            cur_XOR = 0;
        }
    }
 
    // Print Answer
    if (cnt > 2) {
        Console.Write("YES");
    }
    else {
        Console.Write("NO");
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    int []A = { 0, 2, 2 };
    int N =( A.Length);
 
    // Function Call
    possibleEqualArray(A, N);
 
}
}
 
// This code is contributed by shivanisinghss2110.


Javascript


输出:
YES

时间复杂度: O(N 2 )
空间复杂度: O(N)

有效的方法:上述方法可以通过观察来优化,即在数组可以简化为三个相等元素的情况下,结果数组可以表示为{X, X, X}由于, (X^X^X) = XOR(A[0…N-1])它意味着X = XOR(A[0…N-1]) 。案例 1 的处理方式与幼稚方法的处理方式相同。案例2可以解决如下:

  • cntcur_XOR初始化为0 ,并将 A[] 的所有元素的 XOR 存储在tot_XOR中。
  • 遍历数组A[]并跟踪XOR直到cur_XOR中的当前元素。
  • 如果cur_XOR = tot_XOR ,将cnt增加1并初始化cur_XOR = 0
  • 遍历整个数组后,如果cnt > 2的值,可以使用给定的操作使数组的所有元素相等。  

下面是上述方法的实现:

C++

// C++ Program of the above approach
#include 
using namespace std;
 
// Function to check if it is possible
// to make all the array elements equal
// using the given operation
void possibleEqualArray(int A[], int N)
{
    // Stores the XOR of all
    // elements of array A[]
    int tot_XOR = 0;
    for (int i = 0; i < N; i++) {
        tot_XOR ^= A[i];
    }
 
    // Case 1, check if the XOR of
    // the array A[] is 0
    if (tot_XOR == 0) {
        cout << "YES";
        return;
    }
 
    // Case 2
 
    // Maintains the XOR till
    // the current element
    int cur_XOR = 0;
    int cnt = 0;
 
    // Iterate over the array
    for (int i = 0; i < N; i++) {
        cur_XOR ^= A[i];
 
        // If the current XOR is equal
        // to the total XOR increment
        // the count and initialize
        // current XOR as 0
        if (cur_XOR == tot_XOR) {
            cnt++;
            cur_XOR = 0;
        }
    }
 
    // Print Answer
    if (cnt > 2) {
        cout << "YES";
    }
    else {
        cout << "NO";
    }
}
 
// Driver Code
int main()
{
    int A[] = { 0, 2, 2 };
    int N = sizeof(A) / sizeof(int);
 
    // Function Call
    possibleEqualArray(A, N);
 
    return 0;
}

Java

// Java Program of the above approach
import java.util.*;
 
class GFG{
 
// Function to check if it is possible
// to make all the array elements equal
// using the given operation
static void possibleEqualArray(int A[], int N)
{
   
    // Stores the XOR of all
    // elements of array A[]
    int tot_XOR = 0;
    for (int i = 0; i < N; i++) {
        tot_XOR ^= A[i];
    }
 
    // Case 1, check if the XOR of
    // the array A[] is 0
    if (tot_XOR == 0) {
        System.out.print("YES");
        return;
    }
 
    // Case 2
 
    // Maintains the XOR till
    // the current element
    int cur_XOR = 0;
    int cnt = 0;
 
    // Iterate over the array
    for (int i = 0; i < N; i++) {
        cur_XOR ^= A[i];
 
        // If the current XOR is equal
        // to the total XOR increment
        // the count and initialize
        // current XOR as 0
        if (cur_XOR == tot_XOR) {
            cnt++;
            cur_XOR = 0;
        }
    }
 
    // Print Answer
    if (cnt > 2) {
        System.out.print("YES");
    }
    else {
        System.out.print("NO");
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int A[] = { 0, 2, 2 };
    int N =( A.length);
 
    // Function Call
    possibleEqualArray(A, N);
 
}
}
 
// This code is contributed by 29AjayKumar

Python3

# Python 3 Program of the above approach
 
# Function to check if it is possible
# to make all the array elements equal
# using the given operation
def possibleEqualArray(A, N):
   
    # Stores the XOR of all
    # elements of array A[]
    tot_XOR = 0
    for i in range(N):
        tot_XOR ^= A[i]
 
    # Case 1, check if the XOR of
    # the array A[] is 0
    if (tot_XOR == 0):
        print("YES")
        return
    # Case 2
 
    # Maintains the XOR till
    # the current element
    cur_XOR = 0
    cnt = 0
 
    # Iterate over the array
    for i in range(N):
        cur_XOR ^= A[i]
 
        # If the current XOR is equal
        # to the total XOR increment
        # the count and initialize
        # current XOR as 0
        if (cur_XOR == tot_XOR):
            cnt += 1
            cur_XOR = 0
 
    # Print Answer
    if (cnt > 2):
        print("YES")
    else:
        print("NO")
 
# Driver Code
if __name__ == '__main__':
    A = [0, 2, 2]
    N = len(A)
 
    # Function Call
    possibleEqualArray(A, N)
     
    # This code is contributed by SURENDRA_GANGWAR.

C#

// C# Program of the above approach
using System;
 
class GFG{
 
// Function to check if it is possible
// to make all the array elements equal
// using the given operation
static void possibleEqualArray(int []A, int N)
{
   
    // Stores the XOR of all
    // elements of array A[]
    int tot_XOR = 0;
    for (int i = 0; i < N; i++) {
        tot_XOR ^= A[i];
    }
 
    // Case 1, check if the XOR of
    // the array A[] is 0
    if (tot_XOR == 0) {
        Console.Write("YES");
        return;
    }
 
    // Case 2
 
    // Maintains the XOR till
    // the current element
    int cur_XOR = 0;
    int cnt = 0;
 
    // Iterate over the array
    for (int i = 0; i < N; i++) {
        cur_XOR ^= A[i];
 
        // If the current XOR is equal
        // to the total XOR increment
        // the count and initialize
        // current XOR as 0
        if (cur_XOR == tot_XOR) {
            cnt++;
            cur_XOR = 0;
        }
    }
 
    // Print Answer
    if (cnt > 2) {
        Console.Write("YES");
    }
    else {
        Console.Write("NO");
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    int []A = { 0, 2, 2 };
    int N =( A.Length);
 
    // Function Call
    possibleEqualArray(A, N);
 
}
}
 
// This code is contributed by shivanisinghss2110.

Javascript


输出:
YES

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