Finding three numbers whose sum is divisible by a given number - java

How can I search through an array and find every combination of three values whose sum is divisible by a given number(x) in java.
In other words, every combination where (n1+n2+n3) % x == 0.
I know this would be a simple solution using a triple for loop but I need something with a time complexity of O(N^2).
Any idea's?

1 - Hash every (element % x) in the list.
2 - Sum every pair of elements in the list (lets call the sum y) and do modded_y = y % x.
3 - Check if x - modded_y is in the hash table. If it is and it's not one of the other 2 numbers then you found a possible combination. Keep iterating and hashing the combinations you found so that they don't repeat.
This is called a meet in the middle strategy.
It's complexity is O(n + (n^2 * 1)) = O(n^2)

I will call the given array A1.
1) create two structs
struct pair{
int first;
int second;
bool valid;
}
struct third{
int value;
int index;
}
2) using a nested loop, initialize an array B1 of all possible Pairs.
3) Loop through B1. if (A1[B1[i].first] + A1[B1[i].second])%x==0 then set B1[i].valid to true
4) create an array A3 of Thirds that stores the index and value of every element from A1 that is divisible by x.
5) using a nested loop, go through each element of A3 and each element of B1. If B1.valid = true
print A1[B1[i].first] and A1[B1[i].second] with an element from A1[A3.index].
that should give you all combinations without using any triple loops.

Related

What exactly is the "i" in this median task?

Hey i have the task to write a code to compute the median from an array. I My teacher gave me the following instructions:
Algorithm for the list l with length n > 1 and the position i:
divide the n elements from the list L in ⌊n/5⌋ groups with 5 elements and <= 1 group with n mod 5 elements.
compute the median from each of the ⌈n/5⌉ groups
compute recursively the median x of the medians from step 2
partition the list L in 2 lists L1 with all numbers < x and L2 with all numbers > x. Also compute the length l1 and l2 of the lists (x will be on the position k = l1 + 1)
if i = k return x, if i < k compute the first element of L1 recursively and if i > k compute the (i-k)th element in L2 recursively.
So my question is, what exactly is the "i"? i already wrote the code and everything is working good, except step 5 because i don't know what the i is and how to use it. How is it defined and how does it change in the recursion?
This is honestly a too much common term in programming and also a very basic concept. Here, 'i' means current index. So, for instance, if you're on the index 4 and l1 is 3 then i == k (as it's mentioned before that k = l1 + 1), you have to return x!
The algorithm you’ve listed solves the following problem:
Given an (unsorted) array A and an index i, return the ith smallest item in array A.
So, for example, if you have an array A of length 5, then if i = 0 you’re asking for the smallest element in the array, if i = 2 you’re asking for the median, and if i = 4 you’re asking for the largest element of the array.
(This use of the variable i is specific to the problem statement as it was given to you. It’s not something that generally has this meaning.)

Multiply numbers represented as Linked List

I've been trying to solve this problem for a while, now, but none of my approaches have worked so far.
You're given two linked lists that represents big numbers, where the head of the lists represent the least significant digit.
Return a new list which stores the result of the multiplication of the two lists.
I've tried an algorithm that worked for the first list being a single number, but not more than that.
Initialize a new list.
Initialize a carry.
While node 1 is not null:
While node 2 is not null:
If node 3's next is not null, add it's value to the carry;
Set node 3's next as node 1 * node 2's value + carry.
Set node 2 as it's next, set node 3 as it's next.
End while set at section 4
Set node 1 as node 1's next.
End while set at section 3.
Return list set at section 1.
This obviously has problems. I've also tried to set a "powCounter" for each iteration of the first loop, and multiply the value by 10 to the power of powCounter.
But this didn't work either.
I'd really appreciate any help!
Do it like you would on paper.
Presumably, before tasking you to write multiply(a, b), they would have already had you write add(a, b), right? So use that.
You said you already wrote logic for multiply with a single digit, so let calls that multiplySingle(a, digit).
You need one more helper method, e.g. shiftLeft(a, n), which adds n 0's to the end of the number, i.e. to the beginning of the list. E.g. shiftLeft([4,3,2,1], 2) should return [0,0,4,3,2,1], meaning 1234 * 10² = 123400.
So, on paper you would multiply 123 with 456 like this:
123 * 456
45600 = 1 * 456 * 100 = shiftLeft(multiplySingle([6,5,4], 1), 2)
9120 = 2 * 456 * 10 = shiftLeft(multiplySingle([6,5,4], 2), 1)
1368 = 3 * 456 * 1 = shiftLeft(multiplySingle([6,5,4], 3), 0)
=====
56088 = 45600 + 9120 + 1368 = add(add([0,0,6,5,4], [0,2,1,9]), [8,6,3,1])
Good luck writing the code for that.
FYI: The idea for a shiftLeft() method is based on similar methods in the built-in BigInteger and BigDecimal classes.
BigInteger shiftLeft(int n)
Returns a BigInteger whose value is (this << n). The shift distance, n, may be negative, in which case this method performs a right shift. (Computes floor(this * 2ⁿ).)
BigDecimal movePointRight(int n)
Returns a BigDecimal which is equivalent to this one with the decimal point moved n places to the right. If n is non-negative, the call merely subtracts n from the scale. If n is negative, the call is equivalent to movePointLeft(-n). The BigDecimal returned by this call has value (this × 10ⁿ) and scale max(this.scale()-n, 0).

Maximizing GCD with some condition

This is a problem given in HackWithInfy2019 in hackerrank.
I am stuck with this problem since yesterday.
Question:
You are given array of N integers.You have to find a pair (i,j)
which maximizes the value of GCD(a[i],a[j])+(j - i)
and 1<=i< j<=n
Constraints are:
2<= N <= 10^5
1<= a[i] <= 10^5
I've tried this problem using python
Here is an approach that could work:
result = 0
min_i = array[1 ... 100000] initialized to 0
for j in [1, 2, ..., n]
for d in divisors of a[j]
let i = min_i[d]
if i > 0
result = max(result, d + j - i)
else
min_i[d] = j
Here, min_i[d] for each d is the smallest i such that a[i] % d == 0. We use this in the inner loop to, for each d, find the first element in the array whose GCD with a[j] is at least d. When j is one of the possible values for which gcd(a[i], a[j]) + j - i is maximal, when the inner loop runs with d equal to the required GCD, result will be set to the correct answer.
The maximum possible number of divisors for a natural number less than or equal to 100,000 is 128 (see here). Therefore the inner loop runs at most 128 * 100,000 = 12.8 million times. I imagine this could pass with some optimizations (although maybe not in Python).
(To iterate over divisors, use a sieve to precompute the smallest nontrivial divisor for each integer from 1 to 100000.)
Here is one way of doing it.
Create a mutable class MinMax for storing the min. and max. index.
Create a Map<Integer, MinMax> for storing the min. and max. index for a particular divisor.
For each value in a, find all divisors for a[i], and update the map accordingly, such that the MinMax object stores the min. and max. i of the number with that particular divisor.
When done, iterate the map and find the entry with largest result of calculating key + value.max - value.min.
The min. and max. values of that entry is your answer.

climbing stairs the int limitation between two solutions

When working on leetcode 70 climbing stairs: You are climbing a stair case. It takes n steps to reach to the top.Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Here is my first solution:
class Solution {
public int fib (int n){
if (n <= 2) return n;
return fib(n-1) + fib(n-2);
}
public int climbStairs(int n) {
return fib (n+1);
}
}
when n <44, it works, but n >=44, it doesn't work.because of this, it leads to the failure in submission in leetcode.
but when use the 2nd solution, shows below
class Solution {
public int climbStairs(int n) {
if (n <= 2) return n;
int[] allWays = new int[n];
allWays[0] = 1;
allWays[1] = 2;
for (int i = 2; i < n; i++){
allWays[i] = allWays[i-1] + allWays[i-2];
}
return allWays[n-1];
}
}
the second solution is accepted by leetcode. however, when n >=46, it gives a negative number.
Can anyone give me some explanation why the first solution fails? what's the difference between the two solutions? Thanks.
Your intuition is correct. The number of ways to reach the top indeed follows the fibonacci sequence.
The first solution computes the fibonacci numbers recursively (fib(n) = fib(n - 1) + fib(n-2)). To compute any value, the function needs to recursively call itself twice. Every function call takes up space in a region of memory called the stack. Whats probably happening is when n is too large, too many recursive calls are happening and the program runs out of space to execute more calls.
The second solution uses Dynamic programming and memoization. This effectively saves space and computation time. If you don't know these topics, I would encourage you to read into them.
You are getting negative values since the 47th Fibonacci number is greater than the maximum value that can be represented by type int. You can try using long or the BigInteger class to represent larger values.
To understand the solution you need to understand the concept of Dynamic Programming and Recursion
In the first solution to calculate the n-th Fibonacci number, your algorithm is
fib(n)= fib(n-1)+fib(n-2)
But the second solution is more optimized
This approach stores values in an array so that you don't have to calculate fib(n) every time.
Example:
fib(5) = fib(4) + fib(3)
= (fib(3) + fib(2)) + (fib(2) + fib(1))
By first solution, you are calculating fib(2) twice for n = 4.
By second solution you are storing fibonacci values in an array
Example:
for n =4,
first you calculate fib(2) = fib(1)+fib(0) = 1
then you calculate f(3) = f(2)+f(1)
We don't have to calculate the fib(2) since it is already stored in the array.
Check this link for more details
for n = 44 no of ways = 1134903170
and for n = 45 no of ways = 1836311903
so for n = 46 number of ways will be n=44 + n=45 i.e 2971215073
sign INTEGER can only store upto 2147483647 i.e. 2^31 - 1
Because of with for n=46 it is showing -ve number

Subtract number from next number in arraylist

I have an array that holds two doubles. I need to subtract number b from number a.
e.g. 30(number a) - 10(number b)
How do I iterate through my ArrayList and subtract these two numbers? I am not sure if I would need to iterate backwards or forwards.
My code so far. Does not produce the correct result, I am aware d - d would return 0 but I am unsure what to do here:
for (double d = numbersEnteredArrayList.size() - 1; d >= 0; d--) {
equals = d - d;
System.out.println(equals);
}
I'm not sure why you are using an array to store two numbers, but if you just need to subtract them you can access them directly.
double diff = numbersEnteredArrayList.get(1) - numbersEnteredArrayList.get(0);
You can loop through the array in either direction.
Are you trying to output the difference of every sequential pair? If the array was [6 4 2 7] and you want to calculate and display 2 2 -5 (6-4)(4-2)(2-7) then just have the for loop start at 0, go until ArrayList.size()-1 and compute numbersEnteredArrayList.get(d) - numbersEnteredArrayList.get(d+1)
You can keep track of the first value in the array using an int variable then keep subtracting from it as you iterate through the array (of course you would skip the first index).

Categories

Resources