I am trying to assign variable "complement" such that expression Math.abs(array[i]-complement)==diff is true, but I am confused how to implement this. I considered trying to use conditionals, in the case that array[i] is greater than diff, then what would happen to complement, but these conditionals are not always true in all cases. Can someone suggest to me whether this is possible, or not, and if not, what should I do?
Essentially I am trying to find how many ways in an array there exists a pair where their difference is equal to a certain number (variable diff), and I want to find the "complement" so I can quickly look up in a hash table for O(N) time complexity.
This is basically just the 2-diff problem.
I can write out the psuedocode, but the implementation is up to you!
Preface
Your code should run in O(n), so that gives you an idea of how you would want to implement this solution. O(n) suggests that you are looping through your numbers one by one, and that there should not be any nested loops!
You also want to use a HashMap to be able to loop up values quickly.
We use a hashmap to store the complements of each number, so that we can encounter them later!
Psuedocode
let nums be our array of numbers
let diff be our difference
let hash be a hashtable under SUHA
for each num in nums:
if (num in hash):
(num, hash[num]) is our pair!
let c1 = num + diff
let c2 = num - diff
hash[c1] = num
hash[c2] = num
Thats it!
Intuition
The hashmap stores all the complements of the numbers, so when we are looking into the hashmap, we are basically asking, "is this number a complement of another number we have already seen?"
Related
I am trying to think how to solve the Subset sum problem with an extra constraint: The subset of the array needs to be continuous (the indexes needs to be). I am trying to solve it using recursion in Java.
I know the solution for the non-constrained problem: Each element can be in the subset (and thus I perform a recursive call with sum = sum - arr[index]) or not be in it (and thus I perform a recursive call with sum = sum).
I am thinking about maybe adding another parameter for knowing weather or not the previous index is part of the subset, but I don't know what to do next.
You are on the right track.
Think of it this way:
for every entry you have to decide: do you want to start a new sum at this point or skip it and reconsider the next entry.
a + b + c + d contains the sum of b + c + d. Do you want to recompute the sums?
Maybe a bottom-up approach would be better
The O(n) solution that you asked for:
This solution requires three fixed point numbers: The start and end indices, and the total sum of the span
Starting from element 0 (or from the end of the list if you want) increase the end index until the total sum is greater than or equal to the desired value. If it is equal, you've found a subset sum. If it is greater, move the start index up one and subtract the value of the previous start index. Finally, if the resulting total is greater than the desired value, move the end index back until the sum is less than the desired value. In the other case (where the sum is less) move the end index forward until the sum is greater than the desired value. If no match is found, repeat
So, caveats:
Is this "fairly obvious"? Maybe, maybe not. I was making assumptions about order of magnitude similarity when I said both "fairly obvious" and o(n) in my comments
Is this actually o(n)? It depends a lot on how similar (in terms of order of magnitude (digits in the number)) the numbers in the list are. The closer all the numbers are to each other, the fewer steps you'll need to make on the end index to test if a subset exists. On the other hand, if you have a couple of very big numbers (like in the thousands) surrounded by hundreds of pretty small numbers (1's and 2's and 3's) the solution I've presented will get closers to O(n^2)
This solution only works based on your restriction that the subset values are continuous
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.
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).
have been looking the page and lots of great people helping outhere so i have a Lab Assignment and i know i have to do a method concerning the fibonacci numbers to caclulate the number in the position n, but im not quite sure what do put inside the method i know is what i have to think about hope you can give and idea. Having trouble.(not asking to do the hw for me ok) Thank you.
Fibonacci numbers and complexity
Fibonacci numbers are defined recursively as follows:
F(n) = n, for n<=1
F(n) = F(n-1) + F(n-2) for n>1
Write the following methods to compute F(n):
a) A O(2n^n) method based on the recursive definition
b) A O(n) method that uses a loop
c) A O(1) method that uses the closed form solution – feel free to look for this formula on line.
Test all three methods using n = 10; 20; 50; 100; 1,000; 10,000; 100,000 and 1,000,000. If a particular algorithm and input combination does not return an answer in a reasonable amount of time, note that in your report (that is, don’t wait for hours (or worse) for your program to finish).
Well, to answer part c there is a constant time function that will calculate the nth fibonacci number. You can find the formula for it here: http://en.wikipedia.org/wiki/Fibonacci_number#Closed_form_expression
I assume "Hw" means homework, so no code I'm afraid.
a) O(2n) and O(n) are the same thing. Do you mean O(2^n)? This will happen if you use the recursive method without caching the results.
b) This is the "obvious" way to implement it, using a procedural implementation and remembering the last two numbers and using those to calculate the next one. In pseudo-code it would be something like loop { a, b = b, a+b; }
c) This won't work for all n unless you have infinite precision, and infinite precision isn't O(1). For example, when I use doubles fib(73) works out to be 806515533049395, but actually it is 806515533049393. The difference is due to rounding errors when working with floating point numbers.
And regarding the O(n) solution, if you are going to calculate up to fib(1000000) then a 64-bit integer isn't going to be anywhere near enough to store the result. You'll need to use BigIntegers. Adding two BigIntegers is not an O(1) operation, so the O(n) performance I mentioned before is too optimistic.
I have a series of numbers, i.e. 6, 5, 7, 8, 9, 1, which through some mathematical process I will eventually obtain through repetition. For this reason, I want to use a vector to store the last six numbers yielded by this process and then compare the contents of that vector to the series of numbers above. If it identically matches the series of numbers, I will end the program, or if not continue the mathematical procedure.
My question is I how I might go about comparing the series of numbers and the vector efficiently. Originally I was going to use a simple if/else conditional to compare each individual value in the vector with its correspondent in the series(e.g. where v is a Vector filled with six numbers, if (v.get(0) == 6 && v.get(1) == 5 ...)), but considering that this will be evaluated a number of times before the vector equals the series, I'm beginning to wonder if that would be a relatively costly calculation compared to some alternate procedure.
My other idea to do this is to store the series of numbers in a second vector and then compare the two vectors. However, being inexperienced with vectors and Java in general, I'm not sure as to how I might go about doing this and how it might be more efficient than the simple if and else clause mentioned above.
Any advice as to how comparisons between a bunch of numbers and a vector's contents might be done more efficiently? Or if not a vector, than perhaps a list or array instead?
Make a hash value out of your sequence of numbers, example (warning - this hash function is only for demonstration purposes):
[N1,N2,N3,N4,N5] -> N1 xor N2 xor N3 xor N4 xor N5.
Then first you only need to check the hash values of your result vector and the original vector, and only if they match need you to compare each individual number.
You should avoid Vector here, because it's implemented to be thread safe and has some overhead for this. Use LinkedList instead for maximum performance of insert and remove operations and ArrayList for maximum performance of random access.
Example:
void repeatedCompute() {
List<Integer> triggerList = new ArrayList<Integer>() {{
add(6);
add(5);
add(7);
add(8);
add(9);
add(1);
}};
List<Integer> intList = new LinkedList<Integer>();
boolean found = false;
while (!found) {
int nextResult = compute();
intList.add(0, nextResult);
if (intList.size() > triggerList.size()) {
intList.remove(intList.size() - 1);
}
if (intList.equals(triggerList)) {
found = true;
}
}
}
int compute() {
return new Random().nextInt(10);
}
Comparing the lists has the advantage that comparison is stopped after the first element mismatch, you don't have to touch all elements. Comparing lists is quite fast!
I would guess that it wouldn't be too expensive to just keep one vector around with your target numbers in, then populate a new one with your newly generated numbers, then iterate through them comparing. It may be that you're likely to have a failed comparison on the first number, so it only costs you one compare to detect failure.
It seems that you're going to have to collect your six numbers which ever method you use, so just comparing integers won't be too expensive.
Whatever you do, please measure!
You should generate at least two algorithms for your comparison task and compare their performance. Pick the fastest.
However, maybe the first step is to compare the run time of your mathematical process to the comparison task. If your mathematical process runtime is 100 times or more than the comparison, you just have to pick something simple and don't worry.
Note that the && operator short-circuits, i.e. the right operand is only evaluated if the left operand does not determine the result by itself. Hence the comparison will only look at those elements necessary.
I do not think, however, that this will in any case overshadow the time spent on the mathematical calculations used to generate the numbers you compare. Use jvisualvm to investigate where the time is spent.
If you only need to verify that against one set of numbers, then comparing the numbers directly is more efficient. Computing the hash requires you to perform some arithmetic and that is more expensive than comparison. If you need to verify that against multiple sets of numbers than the hash solution would be more efficient.