Related
Find the smallest number M, which is divided by exactly n-1 numbers from the input array. If there is no such M then return -1.
Example:
array = [2,3,5]
Answer :
6
Explanation :
6 can be divided by 2 and 3
Example:
array = [2,3,6]
Answer:
-1
Explanation :
It's not possible in this case so return -1.
My code:
As we need to find the smallest M, I am selecting only the elements from 0 to n-2
public int process(int[] arr) {
int answer = 1;
for(int i=0; i<arr.length-1; i++) {
answer *= arr[i];
}
return answer;
}
This program works for these 2 sample test cases but it was failing for multiple hidden test cases. I trying to understand what I am missing here.
Calculation of the Least Common Multiple (LCM)
A problem inside the task is the calculation of the Least Common Multiple of 2 numbers. The method public int lowerCommonMultiple(int x1, int x2) solves this problem and I think it can be used in other context.
List of the class methods
All the code is included in the methods of the BestMultiple class. These methods (excluding the main) are:
public int[] removeElem(int[] tensArray, int rm_index): used to remove an element from an array
public int leastCommonMultiple(int x1, int x2): calculates the Least Common Multiple of 2 numbers
private int getLeastCommonMultipleNnumber(int[] arr): Calculates the least common multiple of N-1 integer contain in an array
public int process(int[] arr): calculates the least multiple of exactly N-1 number of an array of N integer; it manages many test strange cases (array empty, elem<=0, etc.)
May be the code is not optimized, but I hope it is correct (the output added, shows that it works correctly, at least with the test cases chosen).
public class BestMultiple {
/*++++++++++++++++++++++++++++++++++++++++++++
Method: removeElem() remove an element from
an array.
+++++++++++++++++++++++++++++++++++++++++++*/
public int[] removeElem(int[] tensArray, int rm_index) {
// Create a proxy array of size one less than original array
int[] proxyArray = new int[tensArray.length - 1];
// copy all the elements in the original to proxy array
// except the one at index
for (int i = 0, k = 0; i < tensArray.length; i++) {
// check if index is crossed, continue without copying
if (i == rm_index) {
continue;
}
// else copy the element
proxyArray[k++] = tensArray[i];
}
return proxyArray;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Method: leastCommonMultiple() Calculates the Least Common
multiple for 2 numbers
++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
public int leastCommonMultiple(int x1, int x2) {
int lcm = 1;
int max = x1;
if ((x1 == 0) || (x2 == 0)) {
lcm = 0;
} else {
if (x2 > x1) {
max = x2;
}
for (int i = 2; i <= max; i++) {
int exp_x1 = 0;
int exp_x2 = 0;
int exp = 0;
if (x1 > 1) {
while ((x1 % i) == 0) {
exp_x1++;
x1 /= i;
}
}
if (x2 > 1) {
while ((x2 % i) == 0) {
exp_x2++;
x2 /= i;
}
}
if ((exp_x1 > 0) || (exp_x2 > 0)) {
exp = exp_x1;
if (exp_x2 > exp) {
exp = exp_x2;
}
while (exp > 0) {
lcm *= i;
exp--;
}
}
}
}
return lcm;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Method: getLeastCommonMultipleNnumber()
Calculates the least common multiple of N-1
integer contain in an array
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
public int getLeastCommonMultipleNnumber(int[] arr) {
int multiple = 1;
if (arr.length >= 2) {
multiple = leastCommonMultiple(arr[0], arr[1]);
for (int j = 2; j < arr.length; j++) {
multiple = leastCommonMultiple(multiple, arr[j]);
}
} else {
// array with only 2 elements
multiple = arr[0];
}
return multiple;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Method: process()
Calculates the least multiple of EXACTLY N-1
number of an array of N integer
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
public int process(int[] arr) {
int answer;
if (arr.length <= 1) {
// array contains only one element or is empty => return -1
answer = -1;
} else {
int pos_elem_zero = -1;
int prod = 1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] > 0) {
prod *= arr[i];
} else {
if (arr[i] < 0) {
// integer < 0 are not allowed
return -1;
}
if (pos_elem_zero == -1) {
pos_elem_zero = i;
} else {
// there are more element == 0
return -1;
}
}
}
if (pos_elem_zero >= 0) {
// there is one element == 0
arr = this.removeElem(arr, pos_elem_zero);
return getLeastCommonMultipleNnumber(arr);
}
// managing of normal test case
answer = prod;
for (int i = 0; i < arr.length; i++) {
int elem = arr[i];
int[] arr2 = this.removeElem(arr, i);
int multiple = getLeastCommonMultipleNnumber(arr2);
if (multiple > elem) {
if ((multiple % elem) != 0) {
if (multiple < answer) {
answer = multiple;
}
}
} else {
if (multiple < elem) {
answer = multiple;
}
}
}
if (answer == prod) {
answer = -1;
}
}
return answer;
}
/*++++++++++++++++++++++++++++++++++++++++++
Method: main() Executes test of process()
method
+++++++++++++++++++++++++++++++++++++++++*/
public static void main(String[] args) {
BestMultiple bm = new BestMultiple();
int[] arr1 = {6,30,5,3};
int[] arr2 = {1,2,3};
int[] arr3 = {1,2,3,3};
int[] arr4 = {6,7,5,3};
int[] arr5 = {9,14, 21};
int[] arr6 = {2,4};
int[] arr7 = {2,3,5};
int[] arr8 = {2,3,6};
int[] arr9 = {2};
int[] arr10 = {};
int[] arr11 = {2,3,0};
int[] arr12 = {0,2,3,0};
int[] arr13 = {20,3};
int[] arr14 = {0,6,15};
int[] arr15 = {1,6,15,-1};
int[] arr16 = {1,6,15};
int[] arr17 = {2,3,0,6,15};
System.out.println("{6,30,5,3} --> " + bm.process(arr1));
System.out.println("{1,2,3} --> " + bm.process(arr2));
System.out.println("{1,2,3,3} --> " + bm.process(arr3));
System.out.println("{6,7,5,3} --> " + bm.process(arr4));
System.out.println("{9,14,21} --> " + bm.process(arr5));
System.out.println("{2,4} --> " + bm.process(arr6));
System.out.println("{2,3,5} --> " + bm.process(arr7));
System.out.println("{2,3,6} --> " + bm.process(arr8));
System.out.println("{2} --> " + bm.process(arr9));
System.out.println("{} --> " + bm.process(arr10));
System.out.println("{2,3,0} --> " + bm.process(arr11));
System.out.println("{0,2,3,0} --> " + bm.process(arr12));
System.out.println("{20,3} --> " + bm.process(arr13));
System.out.println("{0,6,15} --> " + bm.process(arr14));
System.out.println("{1,6,15,-1} --> " + bm.process(arr15));
System.out.println("{1,6,15} --> " + bm.process(arr16));
System.out.println("{2,3,0,6,15} --> " + bm.process(arr17));
}
}
Output of the program
The output of the program with the test cases chosen is:
{6,30,5,3} --> -1
{1,2,3} --> 2
{1,2,3,3} --> 3
{6,7,5,3} --> 30
{9,14,21} --> 42
{2,4} --> 2
{2,3,5} --> 6
{2,3,6} --> -1
{2} --> -1
{} --> -1
{2,3,0} --> 6
{0,2,3,0} --> -1
{20,3} --> 3
{0,6,15} --> 30
{1,6,15,-1} --> -1
{1,6,15} --> 6
{2,3,0,6,15} --> 30
You start by writing a method process that computes the minimum number for each subarray with one element excluded:
public static int process(int... arr) {
int min = -1;
for (int i = 0; i < arr.length; ++i) {
int r = process(arr, i);
if (r != -1) {
if (min == -1) {
min = r;
} else {
min = Math.min(min, r);
}
}
}
return min;
}
Where the second process method looks like this:
private static int process(int[] arr, int exclude) {
int result = 0;
for (int i = 0; i < arr.length; ++i) {
if (i != exclude) {
if (result == 0) {
result = arr[i];
} else {
result = lcm(result, arr[i]);
}
}
}
if (result%arr[exclude] == 0) {
return -1;
}
return result;
}
You need a method that computes the LCM of two numbers. Here, I'll use a second method that computes the GCD:
private static int lcm(int a, int b) {
return a*b/gcd(a,b);
}
private static int gcd(int a, int b) {
if (a == 0) {
return b;
} else if (b == 0) {
return a;
} else {
while (a != b) {
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a;
}
}
Examples:
System.out.println(process(2, 3, 5)); // prints 6
System.out.println(process(2, 3, 6)); // prints -1
System.out.println(process(9, 14, 21)); // prints 42 (divisible by 14 and 21, but not by 9
System.out.println(process(6, 7, 5, 3)); // prints 30 (divisible by 6, 5, 3, but not by 7
The way you implemented process() assumes the input array is sorted. But anyway, I don't think sorting will help here. Note that the number satisfying the given conditions can be divided by the biggest number. For [2, 3, 5, 6] it is 6. Dividing the product of all the elements by consecutive elements from the biggest to the lowest and stopping at the first that is not a divisor is also not correct. In the example [2, 4, 5, 6] this would give 2 * 4 * 5 = 40 when the correct answer is 20.
My idea is to use an algorithm inspired by Sieve of Eratosthenes. Note that the number that satisfies the conditions can't be bigger than the product of all the elements. So create a table divisors[] with indices from 0 through the product of the elements of array where divisors[i] indicates how many elements from array divide i. Iterate over elements of array and increment all elements in divisors[i] where i is divided by the element. Then find the first i for which divisors[i] == n - 1.
The limitation is that divisors can be quite big depending on what is the product of array, so applicability will be limited to relatively small values in array.
A food fest is organised at the JLN stadium. The stalls from different states and cities have been set up. To make the fest more interesting, multiple games have been arranged which can be played by the people to win the food vouchers.One such game to win the food vouchers is described below:
There are N number of boxes arranged in a single queue. Each box has an integer I written on it. From the given queue, the participant has to select two contiguous subsequences A and B of the same size. The selected subsequences should be such that the summation of the product of the boxes should be maximum. The product is not calculated normally though. To make the game interesting, the first box of subsequence A is to be multiplied by the last box of subsequence B. The second box of subsequence A is to be multiplied by the second last box of subsequence B and so on. All the products thus obtained are then added together.
If the participant is able to find the correct such maximum summation, he/she will win the game and will be awarded the food voucher of the same value.
Note: The subsequences A and B should be disjoint.
Example:
Number of boxes, N = 8
The order of the boxes is provided below:
1 9 2 3 0 6 7 8
Subsequence A
9 2 3
Subsequence B
6 7 8
The product of the subsequences will be calculated as below:
P1 = 9 * 8 = 72
P2 = 2 * 7 = 14
P3 = 3 * 6 = 18
Summation, S = P1 + P2 + P3 = 72 + 14 + 18 = 104
This is the maximum summation possible as per the requirement for the given N boxes.
Tamanna is also in the fest and wants to play this game. She needs help in winning the game and is asking for your help. Can you help her in winning the food vouchers?
Input Format
The first line of input consists of the number of boxes, N.
The second line of input consists of N space-separated integers.
Constraints
1< N <=3000
-10^6 <= I <=10^6
Output Format
Print the maximum summation of the product of the boxes in a separate line.
Sample TestCase 1
input
8
1 9 2 3 0 6 7 8
output
104
my code is this it is passing only one test can anyone tell me what is wrong and i don't have other test cases since they r hidden
import java.util.Scanner;
import java.util.*;
public class Main {
static class pair {
int first, second;
public pair(int first, int second) {
this.first = first;
this.second = second;
}
}
static int getSubarraySum(int sum[], int i, int j) {
if (i == 0)
return sum[j];
else
return (sum[j] - sum[i - 1]);
}
static int maximumSumTwoNonOverlappingSubarray(int arr[], int N,
int K) {
int l = 0, m = 0;
int a1[] = new int[N / 2];
int a2[] = new int[N / 2];
int prod = 0;
int[] sum = new int[N];
sum[0] = arr[0];
for (int i = 1; i < N; i++)
sum[i] = sum[i - 1] + arr[i];
pair resIndex = new pair(N - 2 * K, N - K);
int maxSum2Subarray =
getSubarraySum(sum, N - 2 * K, N - K - 1)
+ getSubarraySum(sum, N - K, N - 1);
pair secondSubarrayMax =
new pair(N - K, getSubarraySum(sum, N - K, N - 1));
for (int i = N - 2 * K - 1; i >= 0; i--) {
int cur = getSubarraySum(sum, i + K, i + 2 * K - 1);
if (cur >= secondSubarrayMax.second)
secondSubarrayMax = new pair(i + K, cur);
cur = getSubarraySum(sum, i, i + K - 1)
+ secondSubarrayMax.second;
if (cur >= maxSum2Subarray) {
maxSum2Subarray = cur;
resIndex = new pair(i, secondSubarrayMax.first);
}
}
for (int i = resIndex.first; i < resIndex.first + K; i++) {
a1[l] = arr[i];
l++;
}
for (int i = resIndex.second; i < resIndex.second + K; i++) {
a2[m] = arr[i];
m++;
}
for (int i = 0; i < m; i++) {
if (a1[i] != 0 || a2[i] != 0) {
prod = prod + a1[i] * a2[m - (i + 1)];
}
}
return prod;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int k = 0;
int arr[] = new int[a];
for (int i = 0; i < a; i++) {
arr[i] = sc.nextInt();
}
int l = arr.length;
int ar[] = new int[a / 2];
for (int i = 1; i <= a / 2; i++) {
ar[k] = maximumSumTwoNonOverlappingSubarray(arr, l, i);
k++;
}
Arrays.sort(ar);
System.out.println(ar[k - 1]);
}
}
Here's an O(n^2) time, O(1) space solution.
Lets write all O(n^2) multiples in a matrix. For example:
Input {1, 2, 3, -4, 5, 6}
1 2 3 -4 5 6
1 x 2 3 -4 5 6
2 x 6 -8 10 12
3 x -12 15 18
-4 x -20 -24
5 x 30
6 x
Now pick any indexes (i, j), i ≠ j, say (0, 5).
j
1 2 3 -4 5 6
i 1 x 2 3 -4 5 6
2 x 6 -8 10 12
3 x -12 15 18
-4 x -20 -24
5 x 30
6 x
Now imagine we wanted to find the best subarray where i was first, then second, then third, etc. of a valid selection. In each iteration, we would increment i and decrement j, such that we move on the diagonal: 6, 10, -12, each time adding the multiple to extend our selection.
We can do this on each of the diagonals to get the best selection starting on (i, j), where i is first, then second, then third, etc.
Now imagine we ran Kadane's algorithm on each of the diagonals from northeast to southwest (up to where the xs are where i = j). Complexity O(n^2) time. (There's Python code in one of the revisions.)
Here is the code
n=int(input())
l=[]
res=0
l=list(map(int,input().split()))
re=[]
while(True):
if(len(l)==2):
pass
break
else:
n1=l[1]
n2=l[-1]
re.append(n1*n2)
l.remove(n1)
l.remove(n2)
for i in re:
res=res+i
print(res)
#include <iostream>
#include <cassert>
using namespace std;
template<class T> inline void umax(T &a,T b){if(a<b) a = b ; }
template<class T> inline void umin(T &a,T b){if(a>b) a = b ; }
template<class T> inline T abs(T a){return a>0 ? a : -a;}
template<class T> inline T gcd(T a,T b){return __gcd(a, b);}
template<class T> inline T lcm(T a,T b){return a/gcd(a,b)*b;}
typedef long long ll;
typedef pair<int, int> ii;
const int inf = 1e9 + 143;
const ll longinf = 1e18 + 143;
inline int read()
{
int x;scanf(" %d",&x);
return x;
}
const int N = 20001;
int n;
int a[N];
void read_inp()
{
n = read();
assert(1 <= n && n <= 20000);
for(int i = 1; i <= n; i++)
{
a[i] = read();
assert(abs(a[i]) <= int(1e6));
}
}
int main()
{
#ifdef KAZAR
freopen("f.input","r",stdin);
freopen("f.output","w",stdout);
freopen("error","w",stderr);
#endif
read_inp();
ll ans = -longinf;
for(int i = 1; i <= n; i++)
{
{
int l = i - 1, r = i;
ll best = 0ll, cur = 0ll;
while(l >= 1 && r <= n)
{
ll val = (ll)a[l] * a[r];
cur += val;
umin(best, cur);
umax(ans, cur - best);
--l;
++r;
}
}
{
int l = i - 1, r = i + 1;
ll best = 0ll, cur = 0ll;
while(l >= 1 && r <= n)
{
ll val = (ll)a[l] * a[r];
cur += val;
umin(best, cur);
umax(ans, cur - best);
--l;
++r;
}
}
}
printf("%lld\n",ans);
return 0;
}
Here is the code
int main(){
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
cin>>arr[i];
int dp[n][n];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(j==i)
dp[i][j]=0;
else if(j<i)
dp[i][j]=0;
else
dp[i][j]=arr[i]*arr[j];
}
}
cout<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout<<dp[i][j]<<" ";
cout<<endl;
}
cout<<endl;
//find max sum diagonal
long long int global_sum=0;
//get sum of diagonal increasing i
for(int i=0;i<n;i++)
{
long long int curr_sum=0;
int j=i;
int k=n-1;
while(k>=0 && j<n){
curr_sum+=dp[j][k];
k--;
j++;
}
if(curr_sum>global_sum) global_sum=curr_sum;
}
//get sum with decreasing i
for(int i=n-1;i>=0;i--){
long long int curr_sum=0;
int j=i;
int k=0;
while(k<n && j>=0){
curr_sum+=dp[j][k];
j--;
k++;
}
if(curr_sum>global_sum) global_sum=curr_sum;
}
cout<<global_sum;}
This code passes the testcase you gave and other testcases i tried myself. Its O(n^2) complexity.
I'm doing this assignment for my Java course, so the instruction is:
"Write a program that generates 100 random integers in the range 1 to 100, and stores them in an array. Then, the program should call a class method that extracts the numbers that are even multiplesof4intoanarray and returns the array. The program should then call another method that extracts the numbers that are not even multiples of 4 into a separate array and returns the array. Both arrays should then be displayed."
public class Assignment8
{
public static void main (String [] args)
{
int [] numbers = new int [100];
for (int i = 1; i < numbers.length; i++) {
numbers[i] = (int)(Math.random()*((100)+1))+1;
}
int EMO4N [] = evenMultiplesOf4(numbers);
System.out.println("The even multiples of four are: ");
for (int m = 8; m < EMO4N.length; m++) {
System.out.println(EMO4N [m] + " " );
}
int NEMO4N [] = nonEvenMultiplesOf4(numbers);
System.out.println("The numbers that are not even multiples of four are: ");
for (int k = 1; k < NEMO4N.length; k++) {
System.out.println(NEMO4N [k] + " ");
}
}
public static int [] evenMultiplesOf4(int [] numbers)
{
int EMO4 = 8;
for (int x : numbers) {
if (x % 4 == 0 & (x / 4) % 2 == 0) {
EMO4++;
}
}
int [] EMO4N = new int [EMO4];
int y = 8;
for (int m : numbers) {
if(y % 4 == 0 & (y / 4) % 2 == 0) {
EMO4N[y] = m;
y++;
}
}
return EMO4N;
}
public static int [] nonEvenMultiplesOf4( int [] numbers)
{
int NEMO4 = 1;
for (int j : numbers) {
if (j % 4 != 0 || (j / 4) % 2 != 0) {
NEMO4++;
}
}
int [] NEMO4N = new int [NEMO4];
int k = 1;
for (int n : numbers) {
if(k % 4 != 0 || (k / 4) % 2 != 0) {
NEMO4N[k] = n;
k++;
}
}
return NEMO4N;
}
}
The result displayed is always a combination of 0s and some other random numbers.
You have several small logic errors.
You start m and y off at 8, which doesn't make sense as they are meant to keep track of the index that you will be inserting at.
You use the expression if (x % 4 == 0 & (x / 4) % 2 == 0) to determine if the number is divisible by four, but if(x % 4 == 0) is sufficient.
In your loops:
for (int n : numbers) {
if(k % 4 != 0) {
NEMO4N[k] = n;
k++;
}
}
You are checking to see if k is divisible by four, when you should be checking n. Change it to:
for (int n : numbers) {
if(n % 4 != 0) {
NEMO4N[k] = n;
k++;
}
}
I won't provide working code as this seems to be a homework assignment.
Here is working solution - requires Java8.
public static void main(String[] args) throws IOException, ClassNotFoundException {
List c1 = generateArray(100);
Divisors divisors = getDivisors(c1, 4);
print("Even", divisors.evens);
print("Odd", divisors.odds);
}
private static void print(String what, List<Integer> items) {
StringJoiner joiner = new StringJoiner(",");
items.stream().map(String::valueOf).forEach(joiner::add);
System.out.println(what + " divisors are: " + joiner.toString());
}
private static Divisors getDivisors(List<Integer> c1, int i) {
Divisors divisors = new Divisors();
divisors.value = i;
c1.stream()
.filter(value->value>=i)// it is not dividable, so ill skip
.forEach(value -> {
int modulo = value % i;
List<Integer> arr = modulo == 0 ? divisors.evens : divisors.odds;
arr.add(value);
});
return divisors;
}
private static List<Integer> generateArray(int size) {
return IntStream.rangeClosed(1,100).limit(size).boxed().collect(Collectors.toList());
}
static class Divisors {
int value;
List<Integer> evens = new LinkedList<>();
List<Integer> odds = new LinkedList<>();
}
example output:
Even divisors are: 4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100
Odd divisors are: 5,6,7,9,10,11,13,14,15,17,18,19,21,22,23,25,26,27,29,30,31,33,34,35,37,38,39,41,42,43,45,46,47,49,50,51,53,54,55,57,58,59,61,62,63,65,66,67,69,70,71,73,74,75,77,78,79,81,82,83,85,86,87,89,90,91,93,94,95,97,98,99
How to find subsets that contains equal sum in an array.
For example
{1,2,3,4,2}->{1,2,3} && {4,2}
{1,1,3,3,2,8}->{1,3,3,2}&&{1,8}
{1,3,4,7}->no subset
I tried with below code, but not getting the appropriate output.
import java.util.*
public static void main(String[] args) {
int arr[] = {1,3,4,7};
int sum = getSum(arr, arr.length);
int[] solution = new int[arr.length];
find(arr, 0, 0, sum, solution);
}
public static int getSum(int arr[], int n) {
float sum = 0f;
for (int i = 0; i < n; i++)
sum = sum + arr[i];
return Math.round(sum / 2);
}
public static void find(int[] A, int currSum, int index, int sum,
int[] solution) {
if (currSum == sum) {
System.out.println("\nSum found");
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
System.out.print(" " + A[i]);
}
}
} else if (index == A.length) {
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
find(A, currSum, index + 1, sum, solution);
currSum -= A[index];
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution);
}
return;
}
with this Input Array: 1,2,3,4,2 getting below output
1 2 3
1 3 2
2 4
4 2
Input Array: 1,1,3,3,2,8
1 3 3 2
1 8
1 3 3 2
1 8
Input Array:1,3,4,7
1 3 4
1 7
to solve this problem you need to have at least 3 nested loop in your code
the sudocode will be like
for (i=0,i< array.length-1,i++){
for(k=i;k<array.length-1,k++){
fsum=findSum(i/*from*/,k/*to*/,array);
ssum=0;
for(x=k,x<array.length,x++){
secondsum=findSum(k,x,array);
if(fsum==ssum){
prend(i,k,array);
print(k,x,array);
break;
}
}
}
}
note that this is just sudo code need to implement
The recurrence part of your code works fine. There are only two minor flaws in rather peripheral parts:
The two subsets only exists if the sum of the numbers is even. Your code doesn't consider this requirement which is the reason for the failure concerning {1,3,4,7}. For this, the body of the main function is slightly modified so that the recurrence is performed only for even sums.
You should sort out the duplicates which would prevent the repetitions concerning {1,2,3,4,2} and {1,1,3,3,2,8}. For this, the resulting subsets quite simply have to be stored. Then, after the elemination of the duplicates the remaining subsets are printed out. For convenience both functionalities are encapsulated in the added SubsetPair-class which provides the methods storeSubsetPair and printSubsetPairList for storage and printing, respectively.
The modified code is:
import java.util.*;
public class Main {
public static void main(String[] args) {
int arr[] = {1,3,4,7};
int sum = getSum(arr, arr.length);
int[] solution = new int[arr.length];
// find(arr, 0, 0, sum, solution); // REPLACED WITH: -----------------
if (sum % 2 == 0) {
sum = Math.round(sum / 2f);
find(arr, 0, 0,sum, solution);
}
SubsetPair.printSubsetPairList();
// -------------------------------------------------------------------
}
public static int getSum(int arr[], int n) {
// float sum = 0f; // REPLACED WITH: ---------------------------------
int sum = 0;
// -------------------------------------------------------------------
for (int i = 0; i < n; i++)
sum = sum + arr[i];
// return Math.round(sum / 2); // REPLACED WITH: ---------------------
return sum;
// -------------------------------------------------------------------
}
public static void find(int[] A, int currSum, int index, int sum,
int[] solution) {
if (currSum == sum) {
// System.out.println("\nSum found"); // REPLACED WITH: ----------
// for (int i = 0; i < solution.length; i++) {
// if (solution[i] == 1) {
// System.out.print(" " + A[i]);
// }
// }
SubsetPair.storeSubsetPair(A, solution);
// ---------------------------------------------------------------
} else if (index == A.length) {
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
find(A, currSum, index + 1, sum, solution);
currSum -= A[index];
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution);
}
return;
}
}
//NEW: Class for storage and print:
class SubsetPair {
private static List<SubsetPair> subsetPairList = new ArrayList<>();
private List<Integer> subset1 = new ArrayList<>();
private List<Integer> subset2 = new ArrayList<>();
//
// Storage of the subset pair
//
public static void storeSubsetPair(int[] A, int[] solution) {
SubsetPair subsetPair = new SubsetPair();
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
subsetPair.subset1.add(A[i]);
} else {
subsetPair.subset2.add(A[i]);
}
}
if (!subsetPair.isDuplicate()) {
subsetPairList.add(subsetPair);
}
}
// Remove duplicates
private boolean isDuplicate() {
for (SubsetPair subsetPair : subsetPairList) {
if (isEqual(subset1, subsetPair.subset2) && isEqual(subset2, subsetPair.subset1) ||
isEqual(subset1, subsetPair.subset1) && isEqual(subset2, subsetPair.subset2)) {
return true;
}
}
return false;
}
private boolean isEqual(List<Integer> subset1, List<Integer> subset2) {
return subset1.containsAll(subset2) && subset2.containsAll(subset1);
}
//
// Output of the subset pairs
//
public static void printSubsetPairList() {
if (subsetPairList.size() == 0) {
System.out.println("No subset-pairs found!");
} else {
for (int i = 0; i < subsetPairList.size(); i++) {
subsetPairList.get(i).printSubsetPair(i + 1);
}
}
}
private void printSubsetPair(int i) {
System.out.print(i + ". Subset-Pair:\n");
System.out.print("Subset 1: ");
for (Integer i1 : subset1) {
System.out.print(i1 + " ");
}
System.out.println();
System.out.print("Subset 2: ");
for (Integer i2 : subset2) {
System.out.print(i2 + " ");
}
System.out.print("\n\n");
}
}
With those changes the output becomes:
For {1,2,3,4,2} with an even sum of 12:
1. Subset-Pair:
Subset 1: 1 2 3
Subset 2: 4 2
For {1,1,3,3,2,8} with an even sum of 18:
1. Subset-Pair:
Subset 1: 1 3 3 2
Subset 2: 1 8
For {1,3,4,7} with an odd sum of 15:
No subset-pairs found!
For {3,1,1,2,2,1} with an even sum of 10:
1. Subset-Pair:
Subset 1: 3 1 1
Subset 2: 2 2 1
2. Subset-Pair:
Subset 1: 3 2
Subset 2: 1 1 2 1
For {2,4,8} with an even sum of 14:
No subset-pairs found!
As in the comments already stated the problem is related to the "partition problem" which is the task to decide if a multiset of positive integers can be partitioned into two subsets with equal sum. This is in detail explained e.g. in
https://en.wikipedia.org/wiki/Partition_problem or in https://www.geeksforgeeks.org/partition-problem-dp-18/ (the latter includes a Java implementation). But both problems are not exactly identical because the solution of the "partition problem" just answers the question if the multiset can be partitioned into two subsets, but does not explicitly determine the subsets itself.
I need to find out the maximum number of pairs of 1's and 0's that can be found by just altering a single number in a given array.
For example:
If my input is {1,0,0,1,0,0}, here at index position 3 if I replace 1 with 0 then I will get 4 pairs i.e the arrays becomes {1,0,0,0,0,0}, and the pairs are (1,2), (2,3), (3,4), (4,5).
But if I replace index position 0 from 1 to 0 then the array is {0,0,0,1,0,0} here I will get only 3 pairs i.e (0,1), (1,2), (4,5)
I need a program that returns maximum number of pairs possible for a given input array. In this case the program should give 4 as result.
Here the array contains only 1's and 0's.
Here is my program:
public class Program {
public static void main(String[] args) {
Program program = new Program();
int[] a = { 1, 0, 0, 1, 0, 1 };
int response = program.calculate(a);
System.out.println(response);
}
int calculate(int[] input) {
if(input == null || input.length == 0) {
return -1;
}
int length = input.length;
int result = 0;
for (int i = 0; i < length - 1; i++) {
if (input[i] == input[i + 1]) {
result = result + 1;
}
}
int temp = 0;
for (int i = 0; i < length - 1; i++) {
int count = 0;
if (i > 0) {
if (input[i - 1] != input[i]) {
count = count + 1;
} else {
count = count - 1;
}
}
if (i < length - 1) {
if (input[i + 1] != input[i]) {
count = count + 1;
} else {
count = count - 1;
}
}
temp = Math.max(temp, count);
}
return result + temp;
}
}
I was told the program is having some bugs but I was not able to find out where the issue is. I tried passing various values to this program but it is still working without issues. Can you please help me with some combination of inputs for which this program fails.
Well, it seems to be failing for
{ 0, 0, 0, 0, 0, 0, 1}; -> 5 but not {0, 1}; -> 1
{ 1, 0, 1}; -> 2
{ 1, 1, 1}; -> 2
{ 1,0,0,0,0,1,1,0,0,0}; -> 7