📌  相关文章
📜  最长子序列的长度,以使相邻元素的XOR等于K

📅  最后修改于: 2021-05-17 22:59:43             🧑  作者: Mango

给定N个非负整数和整数K的数组arr [] ,我们的想法是找到相邻元素的Xor等于K的最长子序列的长度。

例子:

天真的方法:这个想法是使用动态编程。可以根据以下观察结果解决给定的问题:

请按照以下步骤解决问题:

  • 初始化一个整数(例如ans )来存储最长子序列的长度,并初始化一个数组(例如dp [] )来存储dp状态。
  • 将基本情况定义为dp [0] = 1。
  • [1,N – 1]范围内迭代
    • 如果a [i] ^ a [j] = K ,则在[0,i-1]范围内迭代并将dp [i]更新为max(dp [i],dp [j] +1)
    • ans更新为max(ans,dp [i])
  • 最后,打印最长子序列ans的最大长度。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find maximum length
// of subsequence having XOR of
// adjacent elements equal to K
int xorSubsequence(int a[], int n, int k)
{
 
  // Store maximum length of subsequnce
  int ans = 0;
 
  // Stores the dp-states
  int dp[n] = {0};
 
  // Base case
  dp[0] = 1;
 
  // Iterate over the range [1, N-1]
  for (int i = 1; i < n; i++) {
 
    // Iterate over the range [0, i - 1]
    for (int j = i - 1; j >= 0; j--) {
 
      // If arr[i]^arr[j] == K
      if ((a[i] ^ a[j]) == k)
 
        // Update the dp[i]
        dp[i] = max(dp[i], dp[j] + 1);
    }
 
    // Update the maximum subsequence length
    ans = max(ans, dp[i]);
    dp[i] = max(1, dp[i]);
  }
 
  // If length of longest susequnce
  // is less than 2 then return 0
  return ans >= 2 ? ans : 0;
}
 
// Driver Code
int main()
{
 
  // Input
  int arr[] = { 3, 2, 4, 3, 5 };
  int K = 1;
  int N = sizeof(arr) / sizeof(arr[0]);
 
  // Print the length of longest subsequence
  cout << xorSubsequence(arr, N, K);
  return 0;
}
 
// This code is contributed by Dharanendra L V


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
class GFG {
 
    // Function to find maximum length
    // of subsequence having XOR of
    // adjacent elements equal to K
    public static int xorSubsequence(int a[],
                                     int n, int k)
    {
 
        // Store maximum length of subsequnce
        int ans = 0;
 
        // Stores the dp-states
        int dp[] = new int[n];
 
        // Base case
        dp[0] = 1;
 
        // Iterate over the range [1, N-1]
        for (int i = 1; i < n; i++) {
 
            // Iterate over the range [0, i - 1]
            for (int j = i - 1; j >= 0; j--) {
 
                // If arr[i]^arr[j] == K
                if ((a[i] ^ a[j]) == k)
 
                    // Update the dp[i]
                    dp[i] = Math.max(dp[i], dp[j] + 1);
            }
            // Update the maximum subsequence length
            ans = Math.max(ans, dp[i]);
 
            dp[i] = Math.max(1, dp[i]);
        }
        // If length of longest susequnce
        // is less than 2 then return 0
        return ans >= 2 ? ans : 0;
    }
    // Driver Code
    public static void main(String[] args)
    {
        // Input
        int arr[] = { 3, 2, 4, 3, 5 };
        int K = 1;
        int N = arr.length;
        // Print the length of longest subsequence
        System.out.println(xorSubsequence(arr, N, K));
    }
}


Python3
# Python program for the above approach
 
# Function to find maximum length
# of subsequence having XOR of
# adjacent elements equal to K
def xorSubsequence(a, n, k):
   
    # Store maximum length of subsequnce
    ans = 0;
 
    # Stores the dp-states
    dp = [0] * n;
 
    # Base case
    dp[0] = 1;
 
    # Iterate over the range [1, N-1]
    for i in range(1, n):
 
        # Iterate over the range [0, i - 1]
        for j in range(i - 1, -1, -1):
 
            # If arr[i]^arr[j] == K
            if ((a[i] ^ a[j]) == k):
 
                # Update the dp[i]
                dp[i] = max(dp[i], dp[j] + 1);
 
        # Update the maximum subsequence length
        ans = max(ans, dp[i]);
        dp[i] = max(1, dp[i]);
 
    # If length of longest susequnce
    # is less than 2 then return 0
    return ans if ans >= 2 else 0;
 
# Driver Code
if __name__ == '__main__':
   
    # Input
    arr = [3, 2, 4, 3, 5];
    K = 1;
    N = len(arr);
     
    # Prthe length of longest subsequence
    print(xorSubsequence(arr, N, K));
 
    # This code contributed by shikhasingrajput


C#
// C# program of the above approach
using System;
 
class GFG{
     
// Function to find maximum length
// of subsequence having XOR of
// adjacent elements equal to K
static int xorSubsequence(int[] a, int n,
                          int k)
{
     
    // Store maximum length of subsequnce
    int ans = 0;
 
    // Stores the dp-states
    int[] dp = new int[n];
 
    // Base case
    dp[0] = 1;
 
    // Iterate over the range [1, N-1]
    for(int i = 1; i < n; i++)
    {
         
        // Iterate over the range [0, i - 1]
        for(int j = i - 1; j >= 0; j--)
        {
             
            // If arr[i]^arr[j] == K
            if ((a[i] ^ a[j]) == k)
             
                // Update the dp[i]
                dp[i] = Math.Max(dp[i], dp[j] + 1);
        }
         
        // Update the maximum subsequence length
        ans = Math.Max(ans, dp[i]);
 
        dp[i] = Math.Max(1, dp[i]);
    }
     
    // If length of longest susequnce
    // is less than 2 then return 0
    return ans >= 2 ? ans : 0;
} 
 
// Driver code   
static void Main()
{
     
    // Input
    int[] arr = { 3, 2, 4, 3, 5 };
    int K = 1;
    int N = arr.Length;
     
    // Print the length of longest subsequence
    Console.WriteLine(xorSubsequence(arr, N, K)); 
}
}
 
// This code is contributed by divyeshrabadiya07


C++
// C++ program for above approach
#include 
using namespace std;
 
// Function to find maximum length of subsequence
int xorSubsequence(int a[], int n, int k)
{
    
    // Stores maximum length of subsequence
    int ans = 0;
 
    // Dictionary to store the longest length of
    // subsequence ending at an integer, say X
    map map;
 
    // Stores the maximum length of
    // subsequence ending at index i
    int dp[n] = {0};
 
    // Base case
    map[a[0]] = 1;
    dp[0] = 1;
 
    // Iterate over the range [1, N-1]
    for (int i = 1; i < n; i++)
    {
         
        int dpj;
         
        // Retrieve the longest length of
        // subsequnec ending at integer []a^K
        if(map.find(a[i] ^ k) != map.end())
        {
            dpj = map[a[i] ^ k];
        }
        else{
            dpj = -1;
        }
 
        // If dpj is not NULL
        if (dpj != 0)
 
            // Update dp[i]
            dp[i] = max(dp[i], dpj + 1);
 
        // Update ans
        ans = max(ans, dp[i]);
 
        // Update the maximum length of subsequence
        // ending at element is a[i] in Dictionary
        if(map.find(a[i]) != map.end())
        {
            map[a[i]] = max(map[a[i]]+1, dp[i]);
        }
        else
        {
            map[a[i]] = max(1, dp[i]);
        }
    }
 
    // Return the ans if ans>=2.
    // Otherwise, return 0
    return ans >= 2 ? ans : 0;
}
     
int main()
{
    // Input
    int arr[] = { 3, 2, 4, 3, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 1;
 
    // Print the length of the longest subsequence
    cout << (xorSubsequence(arr, N, K));
 
    return 0;
}
 
// This code is contributed by divyesh072019.


Java
// Java program for above approach
import java.io.*;
import java.util.*;
class GFG
{
 
  // Function to find maximum length of subsequence
  public static int xorSubsequence(int a[], int n, int k)
  {
    // Stores maximum length of subsequence
    int ans = 0;
 
    // HashMap to store the longest length of
    // subsequence ending at an integer, say X
    HashMap map = new HashMap<>();
 
    // Stores the maximum length of
    // subsequence ending at index i
    int dp[] = new int[n];
 
    // Base case
    map.put(a[0], 1);
    dp[0] = 1;
 
    // Iterate over the range [1, N-1]
    for (int i = 1; i < n; i++) {
 
      // Retrieve the longest length of
      // subsequnec ending at integer a[]^K
      Integer dpj = map.get(a[i] ^ k);
 
      // If dpj is not NULL
      if (dpj != null)
 
        // Update dp[i]
        dp[i] = Math.max(dp[i], dpj + 1);
 
      // Update ans
      ans = Math.max(ans, dp[i]);
 
      // Update the maximum length of subsequence
      // ending at element is a[i] in HashMap
      map.put(
        a[i],
        Math.max(map.getOrDefault(a[i], 1), dp[i]));
    }
 
    // Return the ans if ans>=2.
    // Otherwise, return 0
    return ans >= 2 ? ans : 0;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    // Input
    int arr[] = { 3, 2, 4, 3, 5 };
    int N = arr.length;
    int K = 1;
 
    // Print the length of the longest subsequence
    System.out.println(xorSubsequence(arr, N, K));
  }
}


Python3
# Python 3 program for above approach
 
# Function to find maximum length of subsequence
def xorSubsequence( a, n, k):
 
    # Stores maximum length of subsequence
    ans = 0
 
    # HashMap to store the longest length of
    # subsequence ending at an integer, say X
    map = {}
     
    # Stores the maximum length of
    # subsequence ending at index i
    dp = [0]* n
 
    # Base case
    map[a[0]] =  1
    dp[0] = 1
 
    # Iterate over the range[1, N-1]
    for i in range(1, n):
 
        # Retrieve the longest length of
        # subsequnec ending at integer a[] ^ K
         
        # If dpj is not NULL
        if (a[i] ^ k  in map):
 
            # Update dp[i]
               dp[i] = max(dp[i], map[a[i] ^ k] + 1)
 
        # Update ans
        ans = max(ans, dp[i])
 
        # Update the maximum length of subsequence
        # ending at element is a[i] in HashMap
        if a[i] in map:
              map[a[i]] = max(map[a[i]],dp[i])
        else:
            map[a[i]] = max(1, dp[i])
 
    # Return the ans if ans >= 2.
    # Otherwise, return 0
    if ans >= 2 :
      return ans
    return 0
 
# Driver Code
if __name__ == "__main__":
 
    # Input
    arr = [3, 2, 4, 3, 5]
    N = len(arr)
    K = 1
 
    # Print the length of the longest subsequence
    print(xorSubsequence(arr, N, K))
 
    # This code is contributed by chitranayal.


C#
// C# program for above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
    // Function to find maximum length of subsequence
    public static int xorSubsequence(int []a, int n, int k)
    {
       
        // Stores maximum length of subsequence
        int ans = 0;
 
        // Dictionary to store the longest length of
        // subsequence ending at an integer, say X
        Dictionary map = new Dictionary();
 
        // Stores the maximum length of
        // subsequence ending at index i
        int []dp = new int[n];
 
        // Base case
        map.Add(a[0], 1);
        dp[0] = 1;
 
        // Iterate over the range [1, N-1]
        for (int i = 1; i < n; i++)
        {
 
            // Retrieve the longest length of
            // subsequnec ending at integer []a^K
            int dpj = map.ContainsKey(a[i] ^ k)?map[a[i] ^ k]:-1;
 
            // If dpj is not NULL
            if (dpj != 0)
 
                // Update dp[i]
                dp[i] = Math.Max(dp[i], dpj + 1);
 
            // Update ans
            ans = Math.Max(ans, dp[i]);
 
            // Update the maximum length of subsequence
            // ending at element is a[i] in Dictionary
            if(map.ContainsKey(a[i]))
            {
                map[a[i]] = Math.Max(map[a[i]]+1, dp[i]); ;
            }
            else
            {
                map.Add(a[i], Math.Max(1, dp[i]));
            }
        }
 
        // Return the ans if ans>=2.
        // Otherwise, return 0
        return ans >= 2 ? ans : 0;
    }
   
    // Driver Code
    public static void Main(String[] args)
    {
        // Input
        int []arr = { 3, 2, 4, 3, 5 };
        int N = arr.Length;
        int K = 1;
 
        // Print the length of the longest subsequence
        Console.WriteLine(xorSubsequence(arr, N, K));
    }
}
 
// This code is contributed by shikhasingrajput


输出:
3

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

高效方法:可以通过使用Xor和Hashmap的属性进行动态编程来优化上述方法,以存储以整数结尾的子序列的最大长度,从而在DP中实现状态的恒定时间转换。

  • 初始化一个整数,表示ans = 0,以存储最长子序列的长度;初始化一个数组,表示dp [],以存储DP的状态。
  • 初始化一个HashMap,例如mp,以存储以元素结尾的最长子序列长度。
  • 将基本情况定义为dp [0] = 1并将对{arr [0],1}推入mp。
  • [1,N-1]范围内迭代
    • 从HashMap mp中找到最长子序列的长度,例如dpj终止于元素arr [i] ^ K。
    • dp [i]更新为max(dp [i],dpj + 1)并更新HashMap mp中以元素arr [i]结尾的最长子序列长度
    • 更新ans = max(ans,dp [i])。
  • 最后,打印最长子序列ans的最大长度

下面是上述方法的实现:

C++

// C++ program for above approach
#include 
using namespace std;
 
// Function to find maximum length of subsequence
int xorSubsequence(int a[], int n, int k)
{
    
    // Stores maximum length of subsequence
    int ans = 0;
 
    // Dictionary to store the longest length of
    // subsequence ending at an integer, say X
    map map;
 
    // Stores the maximum length of
    // subsequence ending at index i
    int dp[n] = {0};
 
    // Base case
    map[a[0]] = 1;
    dp[0] = 1;
 
    // Iterate over the range [1, N-1]
    for (int i = 1; i < n; i++)
    {
         
        int dpj;
         
        // Retrieve the longest length of
        // subsequnec ending at integer []a^K
        if(map.find(a[i] ^ k) != map.end())
        {
            dpj = map[a[i] ^ k];
        }
        else{
            dpj = -1;
        }
 
        // If dpj is not NULL
        if (dpj != 0)
 
            // Update dp[i]
            dp[i] = max(dp[i], dpj + 1);
 
        // Update ans
        ans = max(ans, dp[i]);
 
        // Update the maximum length of subsequence
        // ending at element is a[i] in Dictionary
        if(map.find(a[i]) != map.end())
        {
            map[a[i]] = max(map[a[i]]+1, dp[i]);
        }
        else
        {
            map[a[i]] = max(1, dp[i]);
        }
    }
 
    // Return the ans if ans>=2.
    // Otherwise, return 0
    return ans >= 2 ? ans : 0;
}
     
int main()
{
    // Input
    int arr[] = { 3, 2, 4, 3, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 1;
 
    // Print the length of the longest subsequence
    cout << (xorSubsequence(arr, N, K));
 
    return 0;
}
 
// This code is contributed by divyesh072019.

Java

// Java program for above approach
import java.io.*;
import java.util.*;
class GFG
{
 
  // Function to find maximum length of subsequence
  public static int xorSubsequence(int a[], int n, int k)
  {
    // Stores maximum length of subsequence
    int ans = 0;
 
    // HashMap to store the longest length of
    // subsequence ending at an integer, say X
    HashMap map = new HashMap<>();
 
    // Stores the maximum length of
    // subsequence ending at index i
    int dp[] = new int[n];
 
    // Base case
    map.put(a[0], 1);
    dp[0] = 1;
 
    // Iterate over the range [1, N-1]
    for (int i = 1; i < n; i++) {
 
      // Retrieve the longest length of
      // subsequnec ending at integer a[]^K
      Integer dpj = map.get(a[i] ^ k);
 
      // If dpj is not NULL
      if (dpj != null)
 
        // Update dp[i]
        dp[i] = Math.max(dp[i], dpj + 1);
 
      // Update ans
      ans = Math.max(ans, dp[i]);
 
      // Update the maximum length of subsequence
      // ending at element is a[i] in HashMap
      map.put(
        a[i],
        Math.max(map.getOrDefault(a[i], 1), dp[i]));
    }
 
    // Return the ans if ans>=2.
    // Otherwise, return 0
    return ans >= 2 ? ans : 0;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    // Input
    int arr[] = { 3, 2, 4, 3, 5 };
    int N = arr.length;
    int K = 1;
 
    // Print the length of the longest subsequence
    System.out.println(xorSubsequence(arr, N, K));
  }
}

Python3

# Python 3 program for above approach
 
# Function to find maximum length of subsequence
def xorSubsequence( a, n, k):
 
    # Stores maximum length of subsequence
    ans = 0
 
    # HashMap to store the longest length of
    # subsequence ending at an integer, say X
    map = {}
     
    # Stores the maximum length of
    # subsequence ending at index i
    dp = [0]* n
 
    # Base case
    map[a[0]] =  1
    dp[0] = 1
 
    # Iterate over the range[1, N-1]
    for i in range(1, n):
 
        # Retrieve the longest length of
        # subsequnec ending at integer a[] ^ K
         
        # If dpj is not NULL
        if (a[i] ^ k  in map):
 
            # Update dp[i]
               dp[i] = max(dp[i], map[a[i] ^ k] + 1)
 
        # Update ans
        ans = max(ans, dp[i])
 
        # Update the maximum length of subsequence
        # ending at element is a[i] in HashMap
        if a[i] in map:
              map[a[i]] = max(map[a[i]],dp[i])
        else:
            map[a[i]] = max(1, dp[i])
 
    # Return the ans if ans >= 2.
    # Otherwise, return 0
    if ans >= 2 :
      return ans
    return 0
 
# Driver Code
if __name__ == "__main__":
 
    # Input
    arr = [3, 2, 4, 3, 5]
    N = len(arr)
    K = 1
 
    # Print the length of the longest subsequence
    print(xorSubsequence(arr, N, K))
 
    # This code is contributed by chitranayal.

C#

// C# program for above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
    // Function to find maximum length of subsequence
    public static int xorSubsequence(int []a, int n, int k)
    {
       
        // Stores maximum length of subsequence
        int ans = 0;
 
        // Dictionary to store the longest length of
        // subsequence ending at an integer, say X
        Dictionary map = new Dictionary();
 
        // Stores the maximum length of
        // subsequence ending at index i
        int []dp = new int[n];
 
        // Base case
        map.Add(a[0], 1);
        dp[0] = 1;
 
        // Iterate over the range [1, N-1]
        for (int i = 1; i < n; i++)
        {
 
            // Retrieve the longest length of
            // subsequnec ending at integer []a^K
            int dpj = map.ContainsKey(a[i] ^ k)?map[a[i] ^ k]:-1;
 
            // If dpj is not NULL
            if (dpj != 0)
 
                // Update dp[i]
                dp[i] = Math.Max(dp[i], dpj + 1);
 
            // Update ans
            ans = Math.Max(ans, dp[i]);
 
            // Update the maximum length of subsequence
            // ending at element is a[i] in Dictionary
            if(map.ContainsKey(a[i]))
            {
                map[a[i]] = Math.Max(map[a[i]]+1, dp[i]); ;
            }
            else
            {
                map.Add(a[i], Math.Max(1, dp[i]));
            }
        }
 
        // Return the ans if ans>=2.
        // Otherwise, return 0
        return ans >= 2 ? ans : 0;
    }
   
    // Driver Code
    public static void Main(String[] args)
    {
        // Input
        int []arr = { 3, 2, 4, 3, 5 };
        int N = arr.Length;
        int K = 1;
 
        // Print the length of the longest subsequence
        Console.WriteLine(xorSubsequence(arr, N, K));
    }
}
 
// This code is contributed by shikhasingrajput
输出:
3

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