How to solve the non-negative subset sum using recursion in Java? - java

I am really confused by a question that says:
Given a set of non-negative integers, and a value sum, the goal is to identify all subsets whose sum of elements is equal to sum. For example, if the set of non-negative integers is {3; 34; 4; 12; 5; 2} and sum = 9, then answer is {4; 5} and {4; 2; 3}.
This question must be solved through a recursive method (one recursion function and one main string[]args function) but I have no idea on how to make it. Can someone give a hint?

Seeing you asked for a hint rather than code, I'll give you a pointer on algorithm to get you started.
Generally recursive algorithms look something like:
recursiveFunction(currentResult, context)
if currentResult satisfies given condition
process currentResult
for each possibleResult in context
recursiveFunction(possibleResult, contextWithResultRemoved)
In your case the signature of the method will be something like:
public void allSubsetsWithSum(int targetSum, Set<Integer> current, Set<Integer> remaining)
The satisfying condition test just compares the sum of current to the target.
The 'for each' would just look at each integer in remaining and move it to current before recursing.
There are efficiency shortcuts such as not processing integers from remaining that will make the sum exceed your target. But that isn't necessary to make the algorithm to work.
Hopefully that will get you started. Ask further questions if you don't understand the hints.

Related

Enter 100 numbers. Determine which number is more: positive or negative

so i have this homework where i have to enter 100 numbers and after that it determines if its positive or negative, been trying for hours but still unsuccesful.
Enter 100 numbers. Determine which number is more: positive or negative. (This is literally the task and nothing more is written)
When approaching a problem, first think it thru. Then write the code.
initialize a positive or negative counter.
start reading in numbers
increment the counter based on the number's sign.
continue with (2) until 100 numbers have been read.
Print out informative information based on the results of the contents of (1) and the count of numbers read.
If you are just trying to find the highest magnitude of either positive or negative numbers you can do this quite easily by checking the absolute value:
import java.util.concurrent.ThreadLocalRandom;
public class MyClass
{
public static void main(String args[])
{
int randomNum = 0;
int largestMagnitude = 0;
for(int i = 0; i < 100; i++)
{
randomNum = ThreadLocalRandom.current().nextInt(-1000, 1000);
if(Math.abs(randomNum) > Math.abs(largestMagnitude))
{
largestMagnitude = randomNum;
}
}
System.out.println("The highest magnitude of number generated was " + largestMagnitude);
}
}
This is an suggestion to people providing answers. When the problem is a homework (as the OP CLEARLY indicated) it is important to ask what are they currently learning in order to properly frame the answer to the lesson. Basically, the most correct answer for industry might not (and often it is not) the most correct answer for what it is being taught.
#Janis Klein, what you are covering in class at the moment is very important. For example, if you are learning about sorting, the answer might be to implement some sort of sorting algorithm. When you sort a collection of numbers, the most negative and the most positive will be the head and tail values in your sorted collection. If you are learning about lists and collections, the answer might be to implement some sort of linked list where the numbers are inserted in natural order (no need to sort). Like in my previous example, once you insert all 100 values into this list, the head and tail values are the most positive and negative values.
However, if all you are learning is to do comparisons of values, you don't need but two variables (one for most positive and one for most negative) and all you will need to do is to compare incoming values and store them into the correct variable if needed. For example, the very first value will be both the most positive and most negative. The second incoming value will be either the most positive or most negative (assuming unique values are always received). From the third value on, the incoming value MIGHT be the most positive, the most negative, or simply neither; in which case, the incoming value is discarded. In the end, the most negative and most positive values will be the values stored in the respective variables.
Again, the scope of the answer MUST be framed based on what you are currently learning in class.

Java recursive methods

Can anyone explain to me how to get the correct answer for this question #10:
It's a sample question listed on the AP Board website for AP Computer Science
It's just a binary search. The answers are just weird because technically an index of a sorted array with no duplicates is "the number of elements less than" the value.
The correct answer (as per #KevinRaoofi's answer) is A. Your question is, however, different:
How to get the correct answer for this question?
There are different ways to do this.
For instance, you should be able to recognize binary search in this code. You take the middle element between low and high. The only "actual" return is if (arr[mid] == num) return mid; which returns index of the element which equals num. One you realize this, it is easy to see that this is exactly what the whole method is doing.
So you get an index of the element which is equal to num. The only answer which mentions index is E, but this is clearly a catch. num is not necessarily the middle element so E is not correct. Also, if in multi-choice you have N answers of more-or-less one type and one answer which is completely different, this is most probably a catch. :) Answers are usually designed to cost you time.
Now that the only answer with index is eliminated, which of A-D is correct? It seems illogical that any of them is correct as they deal with "number of elements", not index. At this point it is easy to dismiss all of the answers as incorrect. But instead, try this on a few examples:
0, 1, 2, 3, 4; num=2; result=2;
2, 4, 6, 8; num=2; result=0;
3, 5, 7, 9, 11; num=11; result=4;
Now checking answers against these results shows that A is right on every occasion. So it must be correct, but why? At this point it should be possible to realize, that index of the element in an array equals the number of elements before this index. And in ascending array these numbers are less than number at the given index (which is num). This explains why A is right on every occasion.

Algorithm/function that returns random number in array in O(1) and creates single permutation [duplicate]

This question already has answers here:
Random shuffling of an array
(31 answers)
Closed 7 years ago.
Intro: This is an interview question I had which I couldn't solve. A code solution will be good (in any language), but an algorithm/pseudocode is also great.
The problem: This problem is about designing an algorithm that solves the following problem:
You are given a function int getRand(int x) that gets an int x and returns an int in the range from 0 to x randomly (exclusively -> [0, k) ). Each call to getRand() is performed in O(1) time.
You are also given an array int[] arr of size k containing integers.
Write a function getRandUnique() that when called will return a random member from arr such that after k requests exactly you will have a full permutation of the members of arr (this actually means that getRandUnique() will return a different member of arr for each call).
Each call to getRandUnique() has to be performed in O(1) time.
You are allowed to use/store global variables etc...
E.g.: Assume arr = [2, 3, 5 , 1]. A call to getRandUnique() will return either 2, 3, 5, 1 in 1/4 probability. A consequent call to getRandUnique() will return on of the remaining 3 members in 1/3 probability and so on...
Attempt: I actually solved this myself (after much trial and error) and posted the solution "Q&A Style". I would love to get some other possible ideas/solutions. I will accept any solution that works as the correct answer (I don't want to accept my own)!
Question: How can this be achieved with all the above restrictions?
Edit: Now I am aware that this problem corresponds to the Fisher–Yates shuffle, even though the specifications are a little different/more strict here.
My solution is as follows:
Define index = 0.
Call and assign index = getRand(k) (remember that k is the size of arr).
Swap arr[index] with arr[k].
Now call and assign index = getRand(k-1). Now you can be certain that you won't get the index k again so you won't have to remove it.
Swap arr[index] with arr[k-1]
Continue doing this until you call the last getRand(1).
Now you have an array arr that is a random permutation of itself as requested (don't even need an additional array).

Array Constraint Satisfaction

Given a range of number 1 through N, where N >=3. you have to take an
array of length 2N and place each number ( from the range 1 to N)
twice. such a that the distance between two indexes of a number is
equal to the number. example
N=3
( 3, 1, 2, 1, 3, 2 )
The solution I'm thinking of is as follows:
Generate every permutation array of the range of numbers, ex: {1,2,3|, {3,2,1}, {2,1,3}, etc.
For each permutation array, run the following functions:
foreach(int number : permutationArray){
addToResultArray(number);
}
addToResultArray(int toBeAdded){
for(int i = 0; i < resultArray.length; i++){
//-1 implies the resultArray is empty at that index
if(resultArray[i]==-1 && resultArray[i+toBeAdded+1]==-1)
resultArray[i] = toBeAdded;
}
}
If the above functions do not cause an out of bounds exception, you have a valid solution.
I do not think this solution is very good. Does anyone have something better?
This can be viewed as a constrained problem: you have 2*N variables V={v1,v2,...,v2n} (representing the array indices) each variable has [1,2,..,N] possible values under the constraints:
Every value is assigned to exactly two variables.
The distance between variables with the same value equals the value itself.
An assignment is a mapping from the set of variables to their possible values. For example [v1=1,v2=3,v3=5] is an assignment for v1,v2 and v3. A given assignment is consistent if it satisfies the constraints. An example to inconsistent assignment is [v1=3,v2=1,v3=3]
An assignment is complete if its cardinality equals the variables size (i.e. 2*N). Otherwise it is a partial assignment. Clearly, our goal is to have one or more complete consistent assignment (a.k.a solution).
So the problem is basically a backtracking search problem. In particular, we have an ordering over the variables. Each time we assign a value to the current variable. If the value makes the current assignment inconsistent, we backtrack.
Your approach is actually a generate-and-test which is inefficient. Generating all solutions and counting them is hard problem in general. In most of the cases, we are looking for one solution.
Here is the interesting part: there is a much more efficient way to do this by propagating the values and detecting backtracking sooner (see constraint propagation).

How to multiply two big big numbers

You are given a list of n numbers L=<a_1, a_2,...a_n>. Each of them is
either 0 or of the form +/- 2k, 0 <= k <= 30. Describe and implement an
algorithm that returns the largest product of a CONTINUOUS SUBLIST
p=a_i*a_i+1*...*a_j, 1 <= i <= j <= n.
For example, for the input <8 0 -4 -2 0 1> it should return 8 (either 8
or (-4)*(-2)).
You can use any standard programming language and can assume that
the list is given in any standard data structure, e.g. int[],
vector<int>, List<Integer>, etc.
What is the computational complexity of your algorithm?
In my first answer I addressed the OP's problem in "multiplying two big big numbers". As it turns out, this wish is only a small part of a much bigger problem which I'm going to address now:
"I still haven't arrived at the final skeleton of my algorithm I wonder if you could help me with this."
(See the question for the problem description)
All I'm going to do is explain the approach Amnon proposed in little more detail, so all the credit should go to him.
You have to find the largest product of a continuous sublist from a list of integers which are powers of 2. The idea is to:
Compute the product of every continuous sublist.
Return the biggest of all these products.
You can represent a sublist by its start and end index. For start=0 there are n-1 possible values for end, namely 0..n-1. This generates all sublists that start at index 0. In the next iteration, You increment start by 1 and repeat the process (this time, there are n-2 possible values for end). This way You generate all possible sublists.
Now, for each of these sublists, You have to compute the product of its elements - that is come up with a method computeProduct(List wholeList, int startIndex, int endIndex). You can either use the built in BigInteger class (which should be able to handle the input provided by Your assignment) to save You from further trouble or try to implement a more efficient way of multiplication as described by others. (I would start with the simpler approach since it's easier to see if Your algorithm works correctly and first then try to optimize it.)
Now that You're able to iterate over all sublists and compute the product of their elements, determining the sublist with the maximum product should be the easiest part.
If it's still to hard for You to make the connections between two steps, let us know - but please also provide us with a draft of Your code as You work on the problem so that we don't end up incrementally constructing the solution and You copy&pasting it.
edit: Algorithm skeleton
public BigInteger listingSublist(BigInteger[] biArray)
{
int start = 0;
int end = biArray.length-1;
BigInteger maximum;
for (int i = start; i <= end; i++)
{
for (int j = i; j <= end; j++)
{
//insert logic to determine the maximum product.
computeProduct(biArray, i, j);
}
}
return maximum;
}
public BigInteger computeProduct(BigInteger[] wholeList, int startIndex,
int endIndex)
{
//insert logic here to return
//wholeList[startIndex].multiply(wholeList[startIndex+1]).mul...(
// wholeList[endIndex]);
}
Since k <= 30, any integer i = 2k will fit into a Java int. However the product of such two integers might not necessarily fit into a Java int since 2k * 2k = 22*k <= 260 which fill into a Java long. This should answer Your question regarding the "(multiplication of) two numbers...".
In case that You might want to multiply more than two numbers, which is implied by Your assignment saying "...largest product of a CONTINUOUS SUBLIST..." (a sublist's length could be > 2), have a look at Java's BigInteger class.
Actually, the most efficient way of multiplication is doing addition instead. In this special case all you have is numbers that are powers of two, and you can get the product of a sublist by simply adding the expontents together (and counting the negative numbers in your product, and making it a negative number in case of odd negatives).
Of course, to store the result you may need the BigInteger, if you run out of bits. Or depending on how the output should look like, just say (+/-)2^N, where N is the sum of the exponents.
Parsing the input could be a matter of switch-case, since you only have 30 numbers to take care of. Plus the negatives.
That's the boring part. The interesting part is how you get the sublist that produces the largest number. You can take the dumb approach, by checking every single variation, but that would be an O(N^2) algorithm in the worst case (IIRC). Which is really not very good for longer inputs.
What can you do? I'd probably start from the largest non-negative number in the list as a sublist, and grow the sublist to get as many non-negative numbers in each direction as I can. Then, having all the positives in reach, proceed with pairs of negatives on both sides, eg. only grow if you can grow on both sides of the list. If you cannot grow in both directions, try one direction with two (four, six, etc. so even) consecutive negative numbers. If you cannot grow even in this way, stop.
Well, I don't know if this alogrithm even works, but if it (or something similar) does, its an O(N) algorithm, which means great performance. Lets try it out! :-)
Hmmm.. since they're all powers of 2, you can just add the exponent instead of multiplying the numbers (equivalent to taking the logarithm of the product). For example, 2^3 * 2^7 is 2^(7+3)=2^10.
I'll leave handling the sign as an exercise to the reader.
Regarding the sublist problem, there are less than n^2 pairs of (begin,end) indices. You can check them all, or try a dynamic programming solution.
EDIT: I adjusted the algorithm outline to match the actual pseudo code and put the complexity analysis directly into the answer:
Outline of algorithm
Go seqentially over the sequence and store value and first/last index of the product (positive) since the last 0. Do the same for another product (negative) which only consists of the numbers since the first sign change of the sequence. If you hit a negative sequence element swap the two products (positive and negative) along with the associagted starting indices. Whenever the positive product hits a new maximum store it and the associated start and end indices. After going over the whole sequence the result is stored in the maximum variables.
To avoid overflow calculate in binary logarithms and an additional sign.
Pseudo code
maxProduct = 0
maxProductStartIndex = -1
maxProductEndIndex = -1
sequence.push_front( 0 ) // reuses variable intitialization of the case n == 0
for every index of sequence
n = sequence[index]
if n == 0
posProduct = 0
negProduct = 0
posProductStartIndex = index+1
negProductStartIndex = -1
else
if n < 0
swap( posProduct, negProduct )
swap( posProductStartIndex, negProductStartIndex )
if -1 == posProductStartIndex // start second sequence on sign change
posProductStartIndex = index
end if
n = -n;
end if
logN = log2(n) // as indicated all arithmetic is done on the logarithms
posProduct += logN
if -1 < negProductStartIndex // start the second product as soon as the sign changes first
negProduct += logN
end if
if maxProduct < posProduct // update current best solution
maxProduct = posProduct
maxProductStartIndex = posProductStartIndex
maxProductEndIndex = index
end if
end if
end for
// output solution
print "The maximum product is " 2^maxProduct "."
print "It is reached by multiplying the numbers from sequence index "
print maxProductStartIndex " to sequence index " maxProductEndIndex
Complexity
The algorithm uses a single loop over the sequence so its O(n) times the complexity of the loop body. The most complicated operation of the body is log2. Ergo its O(n) times the complexity of log2. The log2 of a number of bounded size is O(1) so the resulting complexity is O(n) aka linear.
I'd like to combine Amnon's observation about multiplying powers of 2 with one of mine concerning sublists.
Lists are terminated hard by 0's. We can break the problem down into finding the biggest product in each sub-list, and then the maximum of that. (Others have mentioned this).
This is my 3rd revision of this writeup. But 3's the charm...
Approach
Given a list of non-0 numbers, (this is what took a lot of thinking) there are 3 sub-cases:
The list contains an even number of negative numbers (possibly 0). This is the trivial case, the optimum result is the product of all numbers, guaranteed to be positive.
The list contains an odd number of negative numbers, so the product of all numbers would be negative. To change the sign, it becomes necessary to sacrifice a subsequence containing a negative number. Two sub-cases:
a. sacrifice numbers from the left up to and including the leftmost negative; or
b. sacrifice numbers from the right up to and including the rightmost negative.
In either case, return the product of the remaining numbers. Having sacrificed exactly one negative number, the result is certain to be positive. Pick the winner of (a) and (b).
Implementation
The input needs to be split into subsequences delimited by 0. The list can be processed in place if a driver method is built to loop through it and pick out the beginnings and ends of non-0 sequences.
Doing the math in longs would only double the possible range. Converting to log2 makes arithmetic with large products easier. It prevents program failure on large sequences of large numbers. It would alternatively be possible to do all math in Bignums, but that would probably perform poorly.
Finally, the end result, still a log2 number, needs to be converted into printable form. Bignum comes in handy there. There's new BigInteger("2").pow(log); which will raise 2 to the power of log.
Complexity
This algorithm works sequentially through the sub-lists, only processing each one once. Within each sub-list, there's the annoying work of converting the input to log2 and the result back, but the effort is linear in the size of the list. In the worst case, the sum of much of the list is computed twice, but that's also linear complexity.
See this code. Here I implement exact factorial of a huge large number. I am just using integer array to make big numbers. Download the code from Planet Source Code.

Categories

Resources