Cumulative Sum Of Numbers - c
I have to find the cumulative sum of numbers without using array.Like If n=3 & k=5 then my answer will go like this n
1+2+3+4+5 (sum of k elements)
+ 1+3+6+10+15
+ 1+4+10+20+35
(i.e. n times)
n & k ranging from 1 to 10^9
Here elements from index 2 are cumulative sum from the previous series from index 1 to index x like
second value in second series is 3 which is cumulative sum upto second value in previous series 1+2
third value in second series is 6 which is cumulative sum upto third value in previous series 1+2+3
Similarly third value in third series is 10 which is cumulative sum upto third value in previous series 1+3+6
My approach till know is
//For n==1
for(i=0;i<k;i++)
{
a[i]=i+1;
sum = sum + a[i]%mod;
}
if(n==1)
{
printf("%lld\n",sum%mod);
}
//For n>1
else
{
res = (n-1)*k;
for(w=0;w<res;w++)
{
f = w%k;
if(f==0)
{
a[f] = 1;
sum = sum + a[f]%mod;
}
else
{
a[f] = a[f]+a[f-1];
sum = sum + a[f]%mod;
}
}
printf("%lld\n",sum%mod);
}
Here I have used an array storing the series again and again and finding its cumulative sum but here n*k is going too large.
Please help me out in this by suggesting some optimized approach to do so
Finally I have to find the total sum of all these numbers modulo 1000003 1+2+3+4+5+1+3+6+10+15+1+4+10+20+35 = 120%1000003 = 120
I suggest using recursion since you can't use arrays. If you need a little more getting started, let me know (this sounds a lot like a test question so I don't think I should just spell out the answer).
I can point out one simple observation like whatever be the set of elements, since you have to take out the modulo finally, if that modulo(M) is prime then repeating the cumulative sum n times (where n> M ) you again land to the original set of numbers for M iterations. Then you have to deal with just the remaining n-M iterations.
view: [https://en.wikipedia.org/wiki/Figurate_number ]
Related
How to regroup into two arrays with equal sum?
I encountered a question that I couldn't solve during my algorithm interview. The question goes: Given an array of length n, where n is an even number, regroup the elements in the array into two smaller arrays, each with equal length (n/2), with the condition that the sum of each of these smaller arrays is equal. If this cannot be achieved, return -1. Eg. Input: [1,1,1,2,3,3,3,6] Output: [[1,1,2,6], [1,3,3,3]] Eg. Input: [1,4,5,6] Output: -1 I was thinking about randomly initializing two subarrays and then interchanging two elements so that their difference is at least half the total differences in the sum of two arrays. However, I had trouble coming up with a criterion that would dictate the scenario when the input is illegitimate, and the answer should be -1. Thanks for any help and hints!
OK, I will just post my dumb solution here. I work out all the possible subsequences with sum equal to half of the total sum. Then, check if there is any subsequence with length equal to half of the length of the array. If anyone comes up with a faster solution, please let me know :) from collections import Counter def partition(nums): if sum(nums) % 2 != 0: # if the sum is an odd number it's impossible return -1 nums.sort() target = sum(nums) / 2 out = [] ct = Counter(nums) def dp(cand): # first find out all the sub-sequence with sum equal to n/2 if sum(cand) == target: out.append(cand) remain = target - sum(cand) for i, number in enumerate(nums): if number > remain: break if (cand and number < cand[-1]) or ct[number] == 0: continue if i >= 1 and nums[i - 1] == nums[i]: continue ct[number] -= 1 dp([*cand, number]) ct[number] += 1 dp([]) for sub_array in out: if len(sub_array) != len(nums) / 2: continue # check if there is any subsequence with exactly half length another_array = [] stats = Counter(sub_array) for num, count in ct.items(): another_array += [num] * (count - stats[num]) return [another_array, sub_array] return -1
let sum=0; for (int i=0;i<x.length;i++) {sum=sum+i} if (sum%2!=0){ return - 1;} else { //do your code here // } If the sum of the array doesn't sum up to even number, return - 1. Hope this address your question
Quick select different pivot selection algorithms results
I wrote the following quick-select randomize algorithm that moves the smallest k elements of an array to the beginning of it in linear time (technically worst case O(n^2) but the probability drops exponentially): // This function moves the smallest k elements of the array to // the beginning of it in time O(n). void moveKSmallestValuesToTheLeft( double arr[] , unsigned int n , unsigned int k ) { int l = 0, r = n - 1; //Begginning and end indices of the array while (0 < k && k < n && n > 10) { unsigned int partition_index, left_size, pivot; //Partition the data around a random pivot pivot = generatePivot(arr, l, n, k); //explained later partition_index = partition(arr, l, r, pivot); //standard quick sort partition left_size = partition_index - l + 1; if (k < left_size) { //Continue with left subarray r = partition_index - 1; n = partition_index - l; } else { //Continue with right subarray l += left_size; n -= left_size; k -= left_size; } } if (n <= 10) insertionSort(arr + l, n); } And I tested 3 different methods for generating pivot all of them are based on selecting 5 random candidates and returning one of them, for each method I ran the code 100,000. These were the methods: Choose random 5 elements and return their median Choose random 5 elements, calculate k/n and check which element of the 5 is closest to it. I.e, if k/n <= 1/5 return the min if k/n <= 2/5 return the second smallest value, if k/n <= 3/5 return the median and so on. Exactly the same as method 2 but we give more weight to the pivots closer to the median based on the binomial coefficients of them, i.e. I calculated the binomial coefficients for n=5-1 and got [1 4 6 4 1] then I normalized them and calculated their cum-sum and got [0.0625 0.3125, 0.6875 0.9375 1] and then I did: If k/n <= 0.0625 return the min, if k/n <= 0.3125 return the second smallest value, if k/n <= 0.6875 return the median and so on... My intuition told me that method 2 would perform the best because it always chooses the pivot that would most likely be closest to the k'th smallest element and therefore would probably decrease k or n the most at each iteration, but instead every time I ran the code I got the following results (ranked fastest method to slowest method based an average and worst case times): Average running time: First place (fastest): Method 3 Second place: Method 2 Last place: Method 1 Worst case running time: First place (fastest): Method 1 Second place: Method 3 Last place: Method 2 My question is is there any mathematical way to explain these results or at least give some intuition to them? Because my intuition was completely wrong method 2 didn't outperform neither of the other 2 methods. EDIT So apparently the problem was that I only tested k=n/2 which is an edge case so I got this weird results.
Minimum Size Subarray Sum with sorting
The Minimum Size Subarray Sum problem: given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead. For example, given the array [2,3,1,2,4,3] and s = 7, the subarray [4,3] has the minimal length under the problem constraint. The following is my solution: public int minSubArrayLen(int s, int[] nums) { long sum = 0; int a = 0; if (nums.length < 1) return 0; Arrays.sort(nums); for (int i = nums.length-1; i >= 0; i--) { sum += nums[i]; a++; if (sum>=s) break; } if (sum < s) { return 0; } return a; } This solution was not accepted because it did not pass the following test case: 697439 [5334,6299,4199,9663,8945,3566,9509,3124,6026,6250,7475,5420,9201,9501,38,5897,4411,6638,9845,161,9563,8854,3731,5564,5331,4294,3275,1972,1521,2377,3701,6462,6778,187,9778,758,550,7510,6225,8691,3666,4622,9722,8011,7247,575,5431,4777,4032,8682,5888,8047,3562,9462,6501,7855,505,4675,6973,493,1374,3227,1244,7364,2298,3244,8627,5102,6375,8653,1820,3857,7195,7830,4461,7821,5037,2918,4279,2791,1500,9858,6915,5156,970,1471,5296,1688,578,7266,4182,1430,4985,5730,7941,3880,607,8776,1348,2974,1094,6733,5177,4975,5421,8190,8255,9112,8651,2797,335,8677,3754,893,1818,8479,5875,1695,8295,7993,7037,8546,7906,4102,7279,1407,2462,4425,2148,2925,3903,5447,5893,3534,3663,8307,8679,8474,1202,3474,2961,1149,7451,4279,7875,5692,6186,8109,7763,7798,2250,2969,7974,9781,7741,4914,5446,1861,8914,2544,5683,8952,6745,4870,1848,7887,6448,7873,128,3281,794,1965,7036,8094,1211,9450,6981,4244,2418,8610,8681,2402,2904,7712,3252,5029,3004,5526,6965,8866,2764,600,631,9075,2631,3411,2737,2328,652,494,6556,9391,4517,8934,8892,4561,9331,1386,4636,9627,5435,9272,110,413,9706,5470,5008,1706,7045,9648,7505,6968,7509,3120,7869,6776,6434,7994,5441,288,492,1617,3274,7019,5575,6664,6056,7069,1996,9581,3103,9266,2554,7471,4251,4320,4749,649,2617,3018,4332,415,2243,1924,69,5902,3602,2925,6542,345,4657,9034,8977,6799,8397,1187,3678,4921,6518,851,6941,6920,259,4503,2637,7438,3893,5042,8552,6661,5043,9555,9095,4123,142,1446,8047,6234,1199,8848,5656,1910,3430,2843,8043,9156,7838,2332,9634,2410,2958,3431,4270,1420,4227,7712,6648,1607,1575,3741,1493,7770,3018,5398,6215,8601,6244,7551,2587,2254,3607,1147,5184,9173,8680,8610,1597,1763,7914,3441,7006,1318,7044,7267,8206,9684,4814,9748,4497,2239] The expected answer is 132 but my output was 80. Does anyone have any idea what went wrong with my algorithm/code?
I will simply explain the flaw in the logic rather giving the correct logic to handle the problem statement You are taking the numbers in a specific sequence and then adding them for comparison. Quite easily the case can be different where you take numbers in random order to get the exact sum. For example [2,3,1,2,4,3] and s = 7. Based on your logic Step 1-> Sort the numbers and you get [1,2,2,3,3,4] Step 2-> You pick last 2 number (3,4) to get your sum 7 Lets change the sum to 8 From Step 2-> You get 3+3+4 = 10 so u break out of the loop. After this step you return a = 2 Flaw here is 4+3+1 also makes 8 something your logic skips. Same way 3+3+2 is also possible solution to achieve 8. You sorting the array is first flaw in the logic itself. If you consider subarray of existing arrangement, sorting changes the arrangement therefore you will never be able to get the expected solution.
Finding the sum of all subsets of a given set
Suggest an algorithm for finding the sum of all subsets of a set. For example, if k=3 and the subsets are {1},{2},{3},{1,2},{1,3},{2,3},{1,2,3} then sum of subsets is {1}+{2}+{3}+{1+2}+{1+3}+{2+3}+{1+2+3}=24
For an input {x1, …, xn}, return 2n-1 (x1 + … + xn), since each term appears in that many sums.
Each element appears the same number of times, which happens to be 2n-1 where n is number of elements. So the answer is: count sum of elements in the set and multiply it by 2n-1
Answer: Total no. of Subsets are 2^n. As we don't require an empty set, so total required subsets are 2^n - 1. Now all we have to do is simply get all possible subsets. This algorithm will help. void main() { //Total no. of elements in set = n; //Let's say the Set be denoted as P[n] //declare a global variable sum and initialize to 0. for(int i=1;i<=n;i++) { int r = nCi; //here, r = nCi or you can say n combinations i //it's good to write an extra function named something like "nCi" to evaluate nCi and call it when required. //define a new two dimensional array of size "r","i", say s[r][i] for(int k=0;k<r;k++) { //define a function to get all combination array for s[r][i] using "i" elements out of total "n" //This link will help you with best of code for this particular function //<http://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/> //now for every particular s[r][i], do this for(int j=0;j<i;j++) { sum = sum + s[r][j]; } } } //display total output printf("%d",sum); }
calculate expected cost of final product using atleast k out of n items in c
Suppose I have 4 items and i have to pick at least 1 item to make a product out of them. I have cost corresponding to each item as Item1 -> 4 , Item2 -> 7 , Item3 -> 2 , Item4 -> 5.I have to to find expected cost of the final product means an average of all possible combinations Item used like if I use only 1 item then cost may be 4 , 7 , 2 , 5 and if if i use 2 items the cost would be 4+7 , 4+2 , 4+5 , 7+2 , 7+5 , 2+5 and similarly all combinations for using three items and 4+2+7+5 for using four items.Adding those all combinations and dividng them with no. of combination gives me expected cost of the final product.So I want to find sum of all these combinations then how can I go for it?? I think recursion will be used for calculating these combination but unable to apply ???
Instead of using recursion to generate all the possible subsets, you can use bit manipulation. For the example given with 4 items, there are 2^4 possible subsets. So you can represent these 2^4 subsets using a 4 digit binary number. The binary numbers will count from 0 to 2^4-1=15. And for each number, you check the state of the 4 bits. If the bit is set then that element is included in that subset, otherwise it is not. You can easily implement this logic in the form of a Working Java Program. int[] arr = {4 , 7 , 2 , 5}; double ans = 0; int numCombinations = (int)Math.pow(2, arr.length); // Iterate over all the subsets represented in the form of binary numbers for(int i=0; i<numCombinations; i++){ int sum = 0; // check whether a bit is set or not. If the bit is set, then that // number is present in that subset, else it is not present. for(int bit=0; bit<arr.length; bit++){ if( (i & (1<<bit)) != 0){ sum += arr[bit]; } } ans += (double)sum; } //Divide by numCombinations-1 as we are not considering the empty subset{} System.out.println(ans/(numCombinations-1)); This program correctly calculates the answer as 9.6 for the given case. Running Time O(n.2^n) Edit: A better solution Suppose you are generating all subsets of n elements. Now there are two possibilities for the n the element. It will either be included or it will be not included. So suppose you have all the n-1 element subsets. For all these n-1 element subsets, you will do one of the above mentioned two cases, ie. you will include the nth element or not. Thus, we can say that if we have a total of M subsets, then any element will be present M/2 times. In the given case M is 2^n as we are generating all the subsets. So any element will be present 2^(n-1) times. So the total sum of all the numbers in all the subsets will be Sum of numbers of all subsets = arr[0] * 2^(n-1) + arr1 * 2^(n-1) + .......arr[n] * 2^(n-1) dividing this by the number of subsets will give the answer. Total number of subsets = 2^n - 1. We are subtracting 1 as we are not considering the empty subset {}. So for the given case, answer will become (4+7+2+5) * 2^(n-1) / (2^n - 1) = 9.6 Running Time: O(n)
There is a lot of symmetry in this problem which means you don't need a program to solve it. (1) There are 4 possible "products" with 1 part (2) There are 6 (4*3/2) products with 2 parts (3) There are 4 (4*3*2/(3*2*1) products with 3 parts (4) There is one product with 4 parts. Total number of combinations = 15 (I assume we can ignore the "one product with zero parts"). Now in each case, every item is used the same fractional number of times: for (1), you use each 1/4 of the time for (2), you use each 1/2 of the time for (3), you use each 3/4 of the time for (4), you use them all the time. So each part is used in a total of 1 + 3 + 3 + 1 = 8 out of 15 configurations. Thus the "expected cost" is (8/15) * (4+7+2+5) = 18 * 8 / 15 = 9.6 edit how could you have come up with the number 8/15 without explicitly counting? Well, you could note that you can think of the possible combinations (part is used or part is not used) as a binary number with four digits (since there are four parts) - this has been pointed out in other answers. When you list all binary numbers from 0b0000 to 0b1111 you know every position will have the same number of ones and zeros - 8 of each. Leaving out 0b0000 which is "not a product", you find yourself still with 8 ones for each product - thus 8 out of 15.
If you represent the use of an item as a set bit in an integer then you can simply iterate from 1 to 15 and use bit manipulation to determine the cost. In (pseudo) C cost = 0.0; for(i=1;i<=15;++i) { for(j=0;j<4;++j) { if(i & (1<<j)) cost += item_cost[j]; } } average = cost / 15.0; Edit: Assuming that you want to put a bound of k on the fewest number of items n = 0; cost = 0.0; for(i=1;i<=15;++i) { sum = 0.0; used = 0; for(j=0;j<4;++j) { if(i & (1<<j)) { sum += item_cost[j]; ++used; } } if(used>=k) { cost += sum; ++n; } } average = cost / n;
There is nothing to distinguish your items from each other, and the set of combinations is entirely symmetric, so in the set of all possible combinations, every item is selected the same number of times as every other item. So we can simplify the problem by replacing every item's cost with the average item cost, and then just count the number of items selected in all combinations and the total number of combinations. That makes the average cost of a combination: average item cost * total number of items ----------------------------------------- total number of combinations In the case where k = 1, the total number of combinations is 2n-1 and the total number of items in all the combinations is n×2n-1.
Your problem can be solved mathematically- Let 'n' be total no. of elements & 'k' be no. of items to be consider for combinations. SUM = sum of all elements in array COMBINATIONS = k items selected from n i.e., (n C k) FREQUENCY = frequency of each item in all combinations i.e., (n-1 C k-1) So the solution is- Ans = SUM * FREQUENCY / COMBINATIONS After simplification- Ans = SUM * k / n package com.kvvssut.misc; public class AverageOfCombinations { public static void main(String[] args) { System.out.println(getAverageOfAllKCombinations(new int[]{4,7,2,5,8}, 3)); } private static double getAverageOfAllKCombinations(int[] inputs, int k) { int n = inputs.length; long sum = 0; for (int i = 0; i < n; i++) { sum += inputs[i]; } double output = 0; if (k >= n) { output = sum; } else if (k > 0) { double combinations = 1; double divider = 1; for (int i = n; i > k; i--) { combinations *= i; } for (int i = 2; i <= k; i++) { divider *= i; } combinations /= divider; double frequency = 1; for (int i = n - 1; i > k; i--) { frequency *= i; } divider = 1; for (int i = 2; i < k; i++) { divider *= i; } frequency /= divider; output = sum * frequency / combinations; } return output; } } Plz correct me if wrong.