Given an array arr[] of N non-negative integers and an integer K, the idea is to find the length of the longest subsequence having Xor of adjacent elements equal to K.
Examples:
Input: N = 5, arr[] = {3, 2, 4, 3, 5}, K = 1
Output: 3
Explanation:
All the subsequences having Xor of adjacent element equal to K are {3, 2}, {2, 3}, {4, 5}, {3, 2, 3}.
Therefore, the length of the longest subsequence having xor of adjacent element as 1 is 3.
Input: N = 8, arr[] = {4, 5, 4, 7, 3, 5, 4, 6}, K = 2
Output: 3
Explanation:
All the subsequences having Xor of adjacent element equal to K are {4, 6}, {5, 7}, {7, 5}, {5, 7, 5}.
Therefore, the length of the longest subsequence having xor of adjacent element as 1 is 3
Naive Approach: The idea is to use Dynamic Programming. The given problem can be solved based on the following observations:
- Suppose Dp(i) represent maximum length of subsequence ending at index i.
- Then, transition of one state to another state will be as follows:
- Find index j such that j < i and a[j] ^ a[i] = k.
- Therefore, Dp(i) = max(Dp(j)+1, Dp(i))
Follow the steps below to solve the problem:
- Initialize an integer, say ans, to store the length of the longest subsequence and an array, say dp[], to store the dp states.
- Define base case as dp[0] = 1.
- Iterate over the range [1, N – 1]:
- Iterate over the range [0, i-1] and update dp[i] as max(dp[i], dp[j] + 1) if a[i] ^ a[j] = K.
- Update ans as max(ans, dp[i]).
- Finally, print the maximum length of the longest subsequence ans.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int xorSubsequence( int a[], int n, int k)
{
int ans = 0;
int dp[n] = {0};
dp[0] = 1;
for ( int i = 1; i < n; i++) {
for ( int j = i - 1; j >= 0; j--) {
if ((a[i] ^ a[j]) == k)
dp[i] = max(dp[i], dp[j] + 1);
}
ans = max(ans, dp[i]);
dp[i] = max(1, dp[i]);
}
return ans >= 2 ? ans : 0;
}
int main()
{
int arr[] = { 3, 2, 4, 3, 5 };
int K = 1;
int N = sizeof (arr) / sizeof (arr[0]);
cout << xorSubsequence(arr, N, K);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static int xorSubsequence( int a[],
int n, int k)
{
int ans = 0 ;
int dp[] = new int [n];
dp[ 0 ] = 1 ;
for ( int i = 1 ; i < n; i++) {
for ( int j = i - 1 ; j >= 0 ; j--) {
if ((a[i] ^ a[j]) == k)
dp[i] = Math.max(dp[i], dp[j] + 1 );
}
ans = Math.max(ans, dp[i]);
dp[i] = Math.max( 1 , dp[i]);
}
return ans >= 2 ? ans : 0 ;
}
public static void main(String[] args)
{
int arr[] = { 3 , 2 , 4 , 3 , 5 };
int K = 1 ;
int N = arr.length;
System.out.println(xorSubsequence(arr, N, K));
}
}
|
Python3
def xorSubsequence(a, n, k):
ans = 0 ;
dp = [ 0 ] * n;
dp[ 0 ] = 1 ;
for i in range ( 1 , n):
for j in range (i - 1 , - 1 , - 1 ):
if ((a[i] ^ a[j]) = = k):
dp[i] = max (dp[i], dp[j] + 1 );
ans = max (ans, dp[i]);
dp[i] = max ( 1 , dp[i]);
return ans if ans > = 2 else 0 ;
if __name__ = = '__main__' :
arr = [ 3 , 2 , 4 , 3 , 5 ];
K = 1 ;
N = len (arr);
print (xorSubsequence(arr, N, K));
|
C#
using System;
class GFG{
static int xorSubsequence( int [] a, int n,
int k)
{
int ans = 0;
int [] dp = new int [n];
dp[0] = 1;
for ( int i = 1; i < n; i++)
{
for ( int j = i - 1; j >= 0; j--)
{
if ((a[i] ^ a[j]) == k)
dp[i] = Math.Max(dp[i], dp[j] + 1);
}
ans = Math.Max(ans, dp[i]);
dp[i] = Math.Max(1, dp[i]);
}
return ans >= 2 ? ans : 0;
}
static void Main()
{
int [] arr = { 3, 2, 4, 3, 5 };
int K = 1;
int N = arr.Length;
Console.WriteLine(xorSubsequence(arr, N, K));
}
}
|
Javascript
<script>
function xorSubsequence(a, n, k)
{
let ans = 0;
let dp = new Array(n);
dp.fill(0);
dp[0] = 1;
for (let i = 1; i < n; i++)
{
for (let j = i - 1; j >= 0; j--)
{
if ((a[i] ^ a[j]) == k)
dp[i] = Math.max(dp[i], dp[j] + 1);
}
ans = Math.max(ans, dp[i]);
dp[i] = Math.max(1, dp[i]);
}
return ans >= 2 ? ans : 0;
}
let arr = [ 3, 2, 4, 3, 5 ];
let K = 1;
let N = arr.length;
document.write(xorSubsequence(arr, N, K));
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized by using the property of Xor and Hashmap with dynamic programming to store the maximum length of subsequence ending at an integer, resulting in constant time transition of states in DP.
- Initialize an integer say ans =0 to store the length of the longest subsequence and an array say dp[] to store the state of DP.
- Initialize a HashMap say mp to store the longest length of subsequence ending at an element.
- Define base case as dp[0] = 1 and push the pair {arr[0], 1} in mp.
- Iterate over the range [1, N-1]:
- Find the length of the longest subsequence say dpj ending at element arr[i] ^K from HashMap mp.
- Update dp[i] as max(dp[i], dpj+1) and update the longest length of subsequence ending at element arr[i] in HashMap mp.
- Update the ans = max(ans, dp[i]).
- Finally, print the maximum length of the longest subsequence ans.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int xorSubsequence( int a[], int n, int k)
{
int ans = 0;
map< int , int > map;
int dp[n] = {0};
map[a[0]] = 1;
dp[0] = 1;
for ( int i = 1; i < n; i++)
{
int dpj;
if (map.find(a[i] ^ k) != map.end())
{
dpj = map[a[i] ^ k];
}
else {
dpj = -1;
}
if (dpj != 0)
dp[i] = max(dp[i], dpj + 1);
ans = max(ans, dp[i]);
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 ans >= 2 ? ans : 0;
}
int main()
{
int arr[] = { 3, 2, 4, 3, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 1;
cout << (xorSubsequence(arr, N, K));
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
public static int xorSubsequence( int a[], int n, int k)
{
int ans = 0 ;
HashMap<Integer, Integer> map = new HashMap<>();
int dp[] = new int [n];
map.put(a[ 0 ], 1 );
dp[ 0 ] = 1 ;
for ( int i = 1 ; i < n; i++) {
Integer dpj = map.get(a[i] ^ k);
if (dpj != null )
dp[i] = Math.max(dp[i], dpj + 1 );
ans = Math.max(ans, dp[i]);
map.put(
a[i],
Math.max(map.getOrDefault(a[i], 1 ), dp[i]));
}
return ans >= 2 ? ans : 0 ;
}
public static void main(String[] args)
{
int arr[] = { 3 , 2 , 4 , 3 , 5 };
int N = arr.length;
int K = 1 ;
System.out.println(xorSubsequence(arr, N, K));
}
}
|
Python3
def xorSubsequence( a, n, k):
ans = 0
map = {}
dp = [ 0 ] * n
map [a[ 0 ]] = 1
dp[ 0 ] = 1
for i in range ( 1 , n):
if (a[i] ^ k in map ):
dp[i] = max (dp[i], map [a[i] ^ k] + 1 )
ans = max (ans, dp[i])
if a[i] in map :
map [a[i]] = max ( map [a[i]],dp[i])
else :
map [a[i]] = max ( 1 , dp[i])
if ans > = 2 :
return ans
return 0
if __name__ = = "__main__" :
arr = [ 3 , 2 , 4 , 3 , 5 ]
N = len (arr)
K = 1
print (xorSubsequence(arr, N, K))
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
public static int xorSubsequence( int []a, int n, int k)
{
int ans = 0;
Dictionary< int , int > map = new Dictionary< int , int >();
int []dp = new int [n];
map.Add(a[0], 1);
dp[0] = 1;
for ( int i = 1; i < n; i++)
{
int dpj = map.ContainsKey(a[i] ^ k)?map[a[i] ^ k]:-1;
if (dpj != 0)
dp[i] = Math.Max(dp[i], dpj + 1);
ans = Math.Max(ans, dp[i]);
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 ans >= 2 ? ans : 0;
}
public static void Main(String[] args)
{
int []arr = { 3, 2, 4, 3, 5 };
int N = arr.Length;
int K = 1;
Console.WriteLine(xorSubsequence(arr, N, K));
}
}
|
Javascript
<script>
function xorSubsequence(a, n, k)
{
var ans = 0;
var map = new Map();
var dp = Array(n).fill(0);
map.set(a[0], 1)
dp[0] = 1;
for ( var i = 1; i < n; i++)
{
var dpj;
if (map.has(a[i] ^ k))
{
dpj = map.get(a[i] ^ k);
}
else {
dpj = -1;
}
if (dpj != 0)
dp[i] = Math.max(dp[i], dpj + 1);
ans = Math.max(ans, dp[i]);
if (map.has(a[i]))
{
map.set(a[i] , Math.max(map.get(a[i])+1, dp[i]));
}
else
{
map.set(a[i], Math.max(1, dp[i]));
}
}
return ans >= 2 ? ans : 0;
}
var arr = [3, 2, 4, 3, 5];
var N = arr.length;
var K = 1;
document.write(xorSubsequence(arr, N, K));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)