Finding and storing combinations - java

I have a n-digit number composed of 1's only. I want to replace 1's with 0's in all possible combinations and store the combinations in an array.
How do I find all combinations?
I was thinking of starting with one zero and then increasing the number if zeroes that will replace 1's.
If there are 2 zeroes, for example, then i will keep the position of one zero fixed and move the other, till it reaches the end then i'd do the same for the other zero. But then i'll have to root out the repeated combinations.
Basically, this is getting complicated. I want to know a better way to find combinations!

You are simply trying to generate n-digit binary numbers. It means that you can generate 2^n different numbers. So here you go:
Firstly, calculate 2^n.
Implement a loop, starting from 0 and ending at 2^n.
For every loop variable, take the variable as a decimal and convert
it to binary and append some leading zeros (if necessary) to make it
length of n.
Add the binary to your permutations array.

Related

Maximum product of 3 numbers in an array

I came across this question in a recent interview.
Given an array find the maximum product that can be obtained multiplying any 3 numbers in the array.
The solution I came up with is,
Sort the array
Multiply the 3 largest number.
This is O(nlogn)
Is there a O(n) solution to the problem?
Instead of sorting all the values, you can retain the top three, which is O(3n) which is O(n)
Doing this in a single pass is likely to be more efficient than three passes.
One way of doing this is to do an insertion sort into an array of 3, discarding the lowest value each time. (you can start at the lowest value in the array)
You can also implement this using a series of if/else comparison to update 3 variables.
How about negatives?
The only complication is if you can have negative values e.g. 5 * -4 * -4 > 5 * 5 * 3
For this reason it would makes sense to search for the three largest and the two most negative. You can check whether the largest * the next two largest or largest * the two most negative is bigger.
what if they are all negative?
In this case, you also need the three smallest negative values as well to get the product closest to positive infinity.
You can do it in O(n) as follows:
Find the largest number in O(n); remove the number from the array (make it zero)
Find the largest number among the remaining numbers in O(n); make it zero as well
Find the largest number among the remaining numbers, again in O(n)
You repeat the same O(n) loop three times, so it's O(3*n), which is the same as O(n) because constants are ignored.
This won't cater to negatives
It is relatively easy to modify this algorithm to work with negative numbers. Each pass through the array needs to find the largest and the smallest negative value, so at the end you would have three large positive numbers P0, P1, P2 and thee large negative numbers N0, N1, N2, in ascending order by magnitude. Now you need to compare P0*P1*P2 vs. N1*N2*P2, and pick the larger one.
There are O(n)-time complexity solutions to this problem, but these will only occur depending on the input of your array, as you can read in this article
You can perform this in 1 pass by storing largest elements from array A to to array of 3 say B.
For each element n in array A if n is greater than any element in array B then replace array B element with array A element.
Finally multiply the 3 elements in resulting array. This is constant time. This may still be 3n since you are checking against array of 3 as well.
For negative it would be additional 2 elements which contain the smallest. So it may be 5n but still constant time

Use hashing to find a subarray of strings with minimum total length which contain all the distinct strings in the original array

Hi this a java exercise on hashing. First we have an array of N strings (1<=N<=100000), the program will find the minimum length of the consecutive subseries which contains all distinct strings which present in the original array.
For example, original array is {apple,orange,orange pear,pear apple,pear}
the consecutive subarrays can be {orange, pear, pear, apple}
so answer is 19
I've written a code which visit every element in the array and create a new hash table to find the length of the subarray which contain all the distinct strings. It becomes very very slow once N is larger than 1000. So I hope there is a faster algorithm. Thank you!
Pass through the array once, using a hash to keep track of whether you've seen a word before or not. Count the distinct words in the array by adding to your count only when you're seeing a word for the first time.
Pass through the array a second time, using a hash to keep track of the number of times you've seen each word. Also keep track of the sum of the lengths of all the words you've seen. Keep going until you have seen all words at least once.
Now move the start of the range forward as long as you can do so without reducing a word's count to zero. Remember to adjust your hash and letter count accordingly. This gives you the first range which includes every word at least once, and can't be reduced without excluding a word.
Repeatedly do the following: Move the left end of your range forward by one, and then move the right end forward until you find another instance of the word that you just booted from the left end. Each time you do this, you have another minimal range that includes each word once.
While doing steps 3 and 4, keep track of the minimum length so far, and the start and end of the associated range. You're done when you need to move the right end of your range past the end of the array. At this point you have the right minimum length, and the range that achieves it.
This runs in linear time.

Representing large numbers using linked lists and performing operations

I need to store two extremely large numbers (Strings, since they won't fit in int) in two linked lists, add them and then display the result (again, a String).
I can store the numbers directly into the list.
312312 can be stored as 2->1->3->2->1->3 (actual number will be extremely long)
111119 can be stored as 9->1->1->1->1->1
Then I can add them
11->2->4->3->2->4
Normally I could do 11*10^0 + 2*10^1 +...+ 4*10^5 and get 423431 but all those operations (multiplication, addition and exponentiation) would again be integer operations and since the actual numbers are going to be extremely big, int or long won't support the operations. The final result has to be a string.
So I need a way to convert 11->2->4->3->2->4 into 423431 without using int. Also, I cannot use BigInteger. Can anyone help me?
Well, first thing you need to do is implement carry.
For each digit (that is >= 10), you need to increase the next digit by that digit /10 and set that digit to that digit %10.
So 11->2->... becomes 1->3->....
Then to actually produce the string.
For the most performant option, I suggest StringBuilder.
Just append each digit in the linked-list, then just reverse().toString() (since you started with the smallest number).
Think about how you would do it by hand on paper. If the sum of a pair digits is greater than 9 you write down a carry digit of 1, which you add into the sum of the next pair of digits.
In a computer program you can use a local variable for that: add digits from first and last numbers and the carry from earlier, if sum is greater than.. set carry to 1, else set carry to 0, move on to the next pair...

multiply 2 arraysLists together in java

So I have an two arrayLists that represent two numbers. This is so I don't have to use BigInt. so for example
ArrayList<Integer> LargeInt = [2,3,6,4] would really equal 2,364
ArrayList<Integer> LargeInt2 = [8,7,9,4,6] would be 87,946
my goal is to figure out a way to multiply the two numbers and make the answer to a string. I know that multiplying two numbers would need to be put into another array before put into a string so it won't crash with larger numbers. I also know it will be one for loop put into another. But i am finding it difficult to make a code that multiplies the two numbers. the two arrays being multiplied can be any number.
Assuming that this is homework, here is a no-code explanation of what you need to do:
Define a class that wraps ArrayList<Integer>; let's say you call it ArrayInt
Define an operation that adds two ArrayInts together, and returns a third ArrayInt that equals their sum. You can do it digit by digit, taking care of a possible carry into an extra digit, so you need to size your result accordingly.
Define an operation that multiplies your number by a power of ten by adding zeros to the array list. Again, the operation should return a new ArrayInt, rather than modifying the current one
Define an operation that multiplies a number by a single digit. You can use multiplication, or a simple loop that uses addition. The loop would not run more than nine times, so it shouldn't be too bad.
Combine the three operations that you have (addition, multiplication by a digit, and multiplication by a power of ten) into a simple multiplication algorithm that you learned in the elementary school.

Splitting an array and counting values

I'm trying to figure out how to implement a method that does the following:
The method takes in a text file and counts the number of words up until a specified character "#".
An array is passed as a parameter through the method, this contains a list of sequential numbers. A number in an array corresponds to the position the word occurs in the text file (disregarding #'s) so the 4th word will correspond to a value of 3 (n-1).
The method will count the number of times the word before a # occurs in the array and divide it by the total number of entries between #'s it will then take the average of each time this is done.
So an example to make this clear:
Say you have the text file containing :
Hi my name # is something #
A corresponding array would be:
0,0,1,1,1,2,2,2,2,3,4,4 (a number for each letter in sequence)
The first hash would occur between the 2 and 3. So the 2's represent the word occuring before the #. So we would calculate (total number of 2's)/total number of 0's, 1's and 2's. This would be 4/9.
We would then calculate the same between the two hashes # is something #. 'something' corresponds to a 4, so we would have (total number of 4's)/total number of 3 and 4's.
This would be 2/3.
We would then take the average of 2/3 and 4/9
I hope this is clear, let me know if you need any clarifications.
I'd split() the string for any whitespace chars. Now I have every word in an array, with each cell's index representing the corresponding num, and the cell's content(the word) length is the 'how many 0's or 1's or ..' I have.
That should solve the first part of your problem.
Then you need to find where each # is, its offset that is, but that offset you want to represent in words, not chars. So I'd iterate through the previously created array, and check if the word I stored is a #. If it is I'd update a marker variable (this should hold the previous position/index of the last seen #), and calculate the division you want (4/8 , 2/3 w/e). That is the length of the previous cell's content divided by the sum of length's from the marker until the current index-1.
I think that's about it; the logic. It's not that hard to implement. Just don't forget to check the bounds.

Categories