Interviewstreet Triplet [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
interviewstreet Triplet challenge
There is an integer array d which does not contain more than two elements of the same value. How many distinct ascending triples (d[i] < d[j] < d[k], i < j < k) are present?
Input format:
The first line contains an integer N denoting the number of elements in the array. This is followed by a single line containing N integers separated by a single space with no leading/trailing spaces
Output format:
A single integer that denotes the number of distinct ascending triples present in the array
Constraints:
N <= 10^5
Every element of the array is present at most twice
Every element of the array is a 32-bit positive integer
Sample input:
6
1 1 2 2 3 4
Sample output:
4
Explanation:
The distinct triplets are
(1,2,3)
(1,2,4)
(1,3,4)
(2,3,4)

EDIT: I assumed that the integers were ordered, which wasn't mentioned in your answer. With unordered integers, no optimization is possible, you'd have to use the brute force counting approach. If they are sorted, continue reading.
Thing is, you don't really need a lot of programming here. This is more of a mathematical problem.
First, it doesn't matter if there are 1, 2 or more occurences of an integer. The resulting triplets ave to be unique anyway. This reduces to merely counting how many different integers there are in the array. Name that variable s.
Then we merely apply following formula:
result = 0;
for(first_index = 0; first_index < s; first_index++) {
for(second_index = first_index + 1; second_index < s; second_index++) {
result += s - second_index - 1;
}
}
return result;
This can, however, be simplified. Now, if we reason about the values s - second_index - 1 takes for one outer loop, that's just the row of all integers from 0 to s - 2 reversed! Aren't we glad that there's a formula for its sum: where n is an integer, n * (n + 1) / 2 is the sum of the first n integers.
This means we can optimize our program to:
result = 0;
for(first_index = 0; first_index < s; first_index++) {
result += (s - 2 - first_index) * (s - 2 - first_index + 1) / 2;
}
Note that we can further simplify this to result = (x^3 - 3*x^2 + 2*x) / 6.

Related

How to Make a List of Numbers that Sum to n(n-1)/2 [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
I need to come up with an array of n integers, ranging from 0 to n-1 such that the sum of all of them is n(n-1)/2. How should I do this?
One way that I tried doing it was I randomly picked the first n-1 numbers and then picked the last number in a way such that the sum was n(n-1)/2. If it was in the interval [0, n-1], then I was good. Otherwise, I would recursively just run the same function again. However, when I ran this, I got a StackOverflow Error because the recursion ran too many times (none of the lists I made worked).
Is there a better way to randomly generate such lists in Java?
Try the integers from 0 to n-1. Let n = 6
0 1 2 3 4 5
n(n-1)/2 = 6(6-1)/2 = 6(5)/2 = 15
The trivial solution is to create list 0 through n - 1. (The sum of 0 through n - 1 is n(n - 1) / 2.)
If you want a randomized list, take the above list and shuffle it.
If you want a randomized list that isn't simply a permutation of the list 0 through n - 1:
Start with the above list 0 through n - 1
Shuffle the list.
Repeatedly (until you have reached the required level of randomness) do the following:
randomly select two existing list elements: a and b
generate a random number r such that a + r < n and b - r >= 0
a' <- a + r
b' <- b - r
This can be done iteratively in O(n) operations ... depending on how random you need the result to be.
(I'm not sure how many times you need to repeat step 3 to get "sufficient" randomness, but I think it should be O(n) times.)
One Solution:
import java.lang.Math;
...
public int[] solution(int n) {
int[] solution = new int[n];
int targetSum = (n * (n - 1)) / 2;
int runningSum = 0;
double avgRemainder = 0.0;
for (int i = 0; i < n - 1; i++) {
do {
solution[i] = (int)(Math.random() * n);
avgRemainder = (targetSum - runningSum - solution[i])/(n - (i + 1));
if (avgRemainder >= 0.0 && avgRemainder <= (n - 1)) {
runningSum += solution[i];
}
} while (!(avgRemainder >= 0.0 && avgRemainder <= (n - 1)));
}
solution[n - 1] = targetSum - runningSum;
return solution;
}
This will generate a random number, but before adding it to the list of solutions, it will check to see if it will cause the remaining slots to average outside of the range of acceptable numbers, which includes overshooting the target sum.
The cons to this (particularly if order matters) is that it will cause funneling at the end, if you randomly generate large numbers at the beginning, then obviously the remaining numbers will loop until they are small enough to fit in the solution... for example:
If n = 5
If we randomly generate the first two numbers to be 4
[4, 4, ?, ?, ?]
Then this method will loop the 3rd random number until it is between 0 and 2, and if it is 2...
[4, 4, 2, ?, ?]
Then it will loop the remaining numbers until they are 0.
[4, 4, 2, 0, 0]
This should be fine with larger values of n, and it is iterative instead of recursive.
EDIT:
So actually the very last item must be forced because there will only be one solution for solution[n-1]. I fixed the code above to add that because it was getting an: Exception in thread "main" java.lang.ArithmeticException: / by zero.

Finding all permutations to get the given sum (Coin change problem)

I am trying to solve a classical coin-change (dynamic) problem.
To find number of all unique combinations to get a sum from infinite denominations of coins using dynamic approach, i used this method:
/*
n - number of coins
arr[] - coin denominations
x - total sum
dp[] - array to store number of combinations at index i.
*/
for (int j = 0; j < n; j++)
for (int i = 1; i <= x; i++)
if (arr[j] <= i)
dp[i] = (long) ((dp[i] + dp[i - arr[j]]) % (1e9 + 7));
This gives me all unique possible combinations count:
Eg:
Input:
n=3 x=9
Coins: 2 3 5
Output:
3
So far ,all good.
But i observed that just by interchanging the loops in above snippet, i get all the possible permutations.
for (int i = 1; i <= x; i++)
for (int j = 0; j < n; j++)
if (arr[j] <= i)
dp[i] = (long) ((dp[i] + dp[i - arr[j]]) % (1e9 + 7));
This gives me all unique possible permutations count:
Eg:
Input:
3 9
2 3 5
Output:
8
With debugging and going through each iteration, i mapped a pattern that was formed, but didn't understand the reason behind why i am getting permutations.
Can any one explain me this iteratively. Any help will be appreciated.
Thanks
Both questions can be found here:
Permutations: Coin Combinations 1
Combinations: Coin Combinations 2
The first code with outer loop by coins updates number of ways to compose values dp[] with new coin at every round of outer loop. So after k-th round we have dp[] array filled with combinations of k coins only, and the rest of coins is not used yet. If we will store combinations themselves for sorted coin array, we will see only ordered ones like 1 1 5, and 5 never will go before 1. That is why combinations.
The second code at m-th round of outer loop fills m-th cell dp[m] using all possible coins. So we count for m=7 both 1 1 5 and 1 5 1 and 5 1 1 variants. That is why all permutations are counted here.
In addition for comment: we can make 2d array, where dp[x][c] contains number of permutations with sum x, ending with coin a[c]. Note that in this case we have to join counts of permutations with sum x-a[c]. For reference - 1d and 2d Python code.
def coins1(a, n): #permutations
count = [1]+[0]*n
for x in range(1, n + 1):
for c in a:
if (x-c >= 0):
count[x] += count[x-c]
return count[n]
def coins11(a, n): #permutations 2d
m = len(a)
count = [[1] + [0]*(m-1)] + [[0]*m for i in range(n)]
for x in range(1, n + 1):
for c in range(m):
if x>=a[c]:
count[x][c] += sum(count[x-a[c]])
return sum(count[n])

Meaning of the formula how to find lost element in array?

The task is to find lost element in the array. I understand the logic of the solution but I don't understand how does this formula works?
Here is the solution
int[] array = new int[]{4,1,2,3,5,8,6};
int size = array.length;
int result = (size + 1) * (size + 2)/2;
for (int i : array){
result -= i;
}
But why we add 1 to total size and multiply it to total size + 2 /2 ?? In all resources, people just use that formula but nobody explains how that formula works
The sum of the digits 1 thru n is equal to ((n)(n+1))/2.
e.g. for 1,2,3,4,5 5*6/2 = 15.
But this is just a quick way to add up the numbers from 1 to n. Here is what is really going on.
The series computes the sum of 1 to n assuming they all were present. But by subtracting each number from that sum, the remainder is the missing number.
The formula for an arithmetic series of integers from k to n where adjacent elements differ by 1 is.
S[k,n] = (n-k+1)(n+k)/2
Example: k = 5, n = 10
S[k,n] = 5 6 7 8 9 10
S[k,n] = 10 9 8 7 6 5
S[k,n] = (10-5+1)*(10+5)/2
2S[k,n] = 6 * 15 / 2
S[k,n] = 90 / 2 = 45
For any single number missing from the sequence, by subtracting the others from the sum of 45, the remainder will be the missing number.
Let's say you currently have n elements in your array. You know that one element is missing, which means that the actual size of your array should be n + 1.
Now, you just need to calculate the sum 1 + 2 + ... + n + (n+1).
A handy formula for computing the sum of all integers from 1 up to k is given by k(k+1)/2.
By just replacing k with n+1, you get the formula (n+1)(n+2)/2.
It's simple mathematics.
Sum of first n natural numbers = n*(n+1)/2.
Number of elements in array = size of array.
So, in this case n = size + 1
So, after finding the sum, we are subtracting all the numbers from array individually and we are left with the missing number.
Broken sequence vs full sequence
But why we add 1 to total size and multiply it to total size + 2 /2 ?
The amount of numbers stored in your array is one less than the maximal number, as the sequence is missing one element.
Check your example:
4, 1, 2, 3, 5, 8, 6
The sequence is supposed to go from 1 to 8, but the amount of elements (size) is 7, not 8. Because the 7 is missing from the sequence.
Another example:
1, 2, 3, 5, 6, 7
This sequence is missing the 4. The full sequence would have a length of 7 but the above array would have a length of 6 only, one less.
You have to account for that and counter it.
Sum formula
Knowing that, the sum of all natural numbers from 1 up to n, so 1 + 2 + 3 + ... + n can also be directly computed by
n * (n + 1) / 2
See the very first paragraph in Wikipedia#Summation.
But n is supposed to be 8 (length of the full sequence) in your example, not 7 (broken sequence). So you have to add 1 to all the n in the formula, receiving
(n + 1) * (n + 2) / 2
I guess this would be similar to Missing Number of LeetCode (268):
Java
class Solution {
public static int missingNumber(int[] nums) {
int missing = nums.length;
for (int index = 0; index < nums.length; index++)
missing += index - nums[index];
return missing;
}
}
C++ using Bit Manipulation
class Solution {
public:
int missingNumber(vector<int> &nums) {
int missing = nums.size();
int index = 0;
for (int num : nums) {
missing = missing ^ num ^ index;
index++;
}
return missing;
}
};
Python I
class Solution:
def missingNumber(self, nums):
return (len(nums) * (-~len(nums))) // 2 - sum(nums)
Python II
class Solution:
def missingNumber(self, nums):
return (len(nums) * ((-~len(nums))) >> 1) - sum(nums)
Reference to how it works:
The methods have been explained in the following links:
Missing Number Discussion
Missing Number Solution

Adding Values to a List and Converting to BigInteger - Java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm writing a code that determines the smallest integer that is a sequence of sevens followed by some number of zeros (possibly none) that is divisible by int n. Since this number can be massive, the return value should be a BigInteger.
My code so far has an if-else ladder that covers the case that if any int n is not divisible by two or five is guaranteed to only contain sevens (no zeros). In the case where int n is not divisible by two or five, my thought process was to continue adding sevens to a LinkedList in a while loop, until that list (converted to a BigInteger) is divisible by int n. The same logic goes for the case where int n is divisible by two or five, except a two for-loops would add seven and zero to the list.
My code is getting a runtime error when converting the list to a string and then to a BigInteger, specifically on the line BigInteger numBig = new BigInteger(str);. The error is: "java.lang.NumberFormatException: Zero length BigInteger (in java.math.BigInteger)" Also, I'm not quite sure the logic is sound for the case where int n is divisible by two or five.
You don't need BigInteger for this task. The idea is the following:
First you determine the number of required zeros. Since number composed of only sevens cannot be divided by 2 or 5, the number of zeros is equal to the maximum power of 2 or 5 in number n.
Now we have a number n which is not divisible by 2 or 5. Suppose that a remainder of the division of a number composed of m sevens by n is equal to r:
777...m-times..777 mod n = r
Then number composed of (m+1) sevens will have a remainder 10*r + 7, because
777..(m+1)-times...777 = 777...m-times...7 * 10 + 7
So you can just recalculate the remainder until it becomes zero.
public static BigInteger method(int n) {
int two;
for (two = 0; n % 2 == 0; two++) n /= 2;
int five;
for (five = 0; n % 5 == 0; five++) n /= 5;
int zeros = Math.max(two, five);
int sevens = 1;
int r = 7 % n;
while (r != 0) {
r = (r * 10 + 7) % n;
sevens++;
}
// Now just make a number of 'sevens' sevens and 'zeros' zeros:
StringBuilder result = new StringBuilder();
for (int i = 0; i < sevens; i++) {
result.append("7");
}
for (int i = 0; i < zeros; i++) {
result.append("0");
}
return new BigInteger(result.toString());
}
"Zero length BigInteger" means you're trying to create a BigInteger from something that has length of 0. The stack trace would tell you on which line exactly.
I would guess the bug is in your convert method. If you pass in an empty list, it tries to convert an empty string into BigInteger with new BigInteger("")
I don't know what your algorithm is supposed to do in this case. If for example you want to convert an empty list into the number zero, you can do:
if (res.isEmpty()) return BigInteger.ZERO;

Why does my code fail the hidden input test cases?

This is the problem to be solved:
John is assigned a new task today. He is given an array A containing N integers. His task is to update all elements of array to some minimum value x , that is, A[i] = x; 1 <= i <= N; such that sum of this new array is strictly greater than the sum of the initial array.
Note that x should be as minimum as possible such that the sum of the new array is greater than the sum of the initial array.
Input Format:
First line of input consists of an integer N denoting the number of elements in the array A.
Second line consists of N space separated integers denoting the array elements.
Output Format:
The only line of output consists of the value of x.
Sample Input:
5
12345
Sample Output:
4
Explanation:
Initial sum of array= 1 + 2 + 3 + 4 + 5 = 15
When we update all elements to 4, sum of array = 4 + 4 + 4 + 4 + 4 = 20 which is greater than 15.
Note that if we had updated the array elements to 3, sum = 15 which is not greater than 15. So, 4 is the minimum value to which array elements need to be updated.
** ==> Here is my code. How can I improve it? or What is the problem in this code? **
import java.util.Scanner;
public class Test2 {
public static void main(String []args){
Scanner s=new Scanner(System.in);
int check=0, sum=0, biggest=0;
int size=s.nextInt();
if(size>=1 && size<=100000) {
int[] arr=new int[size];
for(int i=0; i<size; i++){
int temp=s.nextInt();
if(temp>=1 && temp<=1000) {
arr[i] = temp;
biggest=biggest > temp ? biggest:temp;
sum=sum+temp;
}
else break;
}
for(int i=1; i<biggest; i++){
check=(size*i)>sum ? i:0;
}
System.out.print(check);
}
else System.err.print("Invalid input size");
}
}
Issue:
for(int i=1; i<biggest; i++){
check=(size*i)>sum ? i:0;
}
There are 2 problems with this, hence it doesn't work. They are as follows-
(size*i)>sum ? i - The problem statement states that it needs minimum possible sum greater than sum of array of elements. Your code blindly assigns i to check without checking the minimality.
check=(size*i)>sum ? i:0 - So, even if you had come across some integer previously, you lost it because you assigned it to 0 if the condition is not satisfied.
I will share my idea of how would I go about this.
Approach 1
Sum all elements like you did.
Now, take average of elements - sum / size of the array. Let's say we store it in a variable average.
Print average + 1 as your answer, as that is the value that could give you minimum possible sum > sum of array itself.
Time Complexity: O(n), where n is size of the array.
Space Complexity: O(1)
Approach 2
Sum all elements like you did.
Calculate min and max for the array and store it in variables, say mini and maxi.
Now, do a binary search between mini and maxi and keep checking the minimum sum > sum criteria.
In this process, you will have variables like low, mid and high.
low = mini,high = maxi
while low <= high:
mid = low + (high - low) / 2
If mid * size <= sum,
low = mid + 1
else
high = mid - 1
Now, print low as your answer.
Let range = maxi - mini.
Time Complexity: O(n) + O(log(range)) = O(n) asymptotically, where n is size of the array.
Space Complexity: O(1)
Not sure if I completely followed what your attempt was, but there should be a pretty straightfoward solution. You know the size of the array and you can easily iterate through the array to get the value of the elements stored in it. All you need to do to find your min x is to take sumOfArray/size of array and then add one to the result to make your result higher.
In your example 15/5=3. 3+1 = 4 so that's your answer. If the numbers summed to 43, 43/5 = 8 r 3, so your answer is 9 (9*5=45). Etc.
When trying some other test cases, then the results are wrong. Try:
Input:
5
1 1 1 1 5
Expected Output: 2 Actual Output: 4
and
Input:
5
5 5 5 5 5
Expected Output: 6 Actual Output: 0

Categories