Write a function which computes the perfect sums in an array? - java

Perfect sums is the sum of two or more number of elements of arrays whose sum is equal to a given number. Return 999 if not found.
my method signature is:
public static int persfectSum(int arr[], int input)
For example:
arr={2,3,5,6,8,10}
input = 10;
5+2+3= 10
2+8 = 10
So, the output is 2;

It is a variation of Subset-Sum problem - with an additional constraint on the size of the subset (larger then 1).
The problem is NP-Complete, but for relatively small integers can be solved using Dynamic Programming in pseudo-polynomial time.
A possibly simpler alternative which is feasible for small arrays is brute-force - just search all possible subsets, and verify for each if it matches the sum.
I believe these guidelines are more then enough as a starter for you to start programming the problem and solve your problem (HW?) on your own.
Good luck.

int PerfectSums(int n, int a[], int sum)
{
int dp[n + 1][sum + 1] ;
dp[0][0] = 1;
for (int i = 1; i <= sum; i++)
dp[0][i] = 0;
for (int i = 1; i <= n; i++)
dp[i][0] = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= sum; j++)
{
if (a[i - 1] > j)
dp[i][j] = dp[i - 1][j];
else
{
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - a[i - 1]];
}
}
}
return (dp[n][sum] == 0 ? 999 : dp[n][sum] ) ;
}

Related

TapeEquilibrium, Solution Failing Two Edge Cases

Currently working on problems from codility for practice, and for some reason I'm unable to get more than 83% correctness overall, originally I solved it with 100% correctness but with N^2 time complexity (it needs to be N or lower)
I've adjusted my code to be able to solve in O(N) but now my correctness has dropped to 77%, I'm currently trying to solve for cases of 2 elements
ie) [1000,-1000] should return 2000, but I return a 0;
Link to Question on Codility:https://app.codility.com/programmers/lessons/3-time_complexity/tape_equilibrium/
The question:
A non-empty array A consisting of N integers is given. Array A represents numbers on a tape.
Any integer P, such that 0 < P < N, splits this tape into two non-empty parts: A[0], A[1], ..., A[P − 1] and A[P], A[P + 1], ..., A[N − 1].
The difference between the two parts is the value of: |(A[0] + A[1] + ... + A[P − 1]) − (A[P] + A[P + 1] + ... + A[N − 1])|
In other words, it is the absolute difference between the sum of the first part and the sum of the second part.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [2..100,000];
each element of array A is an integer within the range [−1,000..1,000]
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
int pval = Integer.MAX_VALUE;
int sum = 0;
int pone = 0;
int ptwo = 0;
int currdiff = 0;
for(int i = 0; i<A.length; i++ ){
sum += A[i];
}
ptwo = sum;
for(int j = 0; j< A.length; j++){
pone += A[j];
ptwo -= A[j];
currdiff = Math.abs(ptwo - pone);
if(currdiff < pval)
pval = currdiff;
}
return pval;
}
}
Any integer P, such that 0 < P < N, splits this tape into two non-empty parts
The "non-empty" is crucial here. If you would try printing both parts in the second loop you would see that in the last iteration the second part is empty.
All you need to do is skip the last iteration in you loop:
public int solution(int[] A) {
int pval = Integer.MAX_VALUE;
int sum = 0;
int pone = 0;
int ptwo = 0;
int currdiff = 0;
for(int i = 0; i<A.length; i++ ){
sum += A[i];
}
ptwo = sum;
for(int j = 0; j< A.length-1; j++){ //<- notice -1 here
pone += A[j];
ptwo -= A[j];
currdiff = Math.abs(ptwo - pone);
if(currdiff < pval)
pval = currdiff;
}
return pval;
}

How to calculate space and time complexity for this code

public static int desc(int number) {
// Time complexity = 2n+n2
// space complexity = ?
int i, j, temp;
int array[] = new int[Integer.toString(number).length()];
for (i = 0; i < array.length; i++)
array[i] = Integer.toString(number).charAt(i) - '0';
for (i = 0; i < array.length - 1; i++) {
for (j = 0; j < array.length - i - 1; j++) {
if (array[j] < array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
StringBuilder strNum = new StringBuilder();
for (int k : array) {
strNum.append(k);
}
int finalInt = Integer.parseInt(strNum.toString());
System.out.println(finalInt);
return finalInt;
}
This is my code as per my understanding I am able to calculate time complexity please suggest if the time complexity is correct or not and also help me to calculate the space complexity of this program I am bit confuse on how to calculate of space complexity .
First let's optimize your code from:
int array[] = new int[Integer.toString(number).length()];
for (i = 0; i < array.length; i++)
array[i] = Integer.toString(number).charAt(i) - '0';
to:
String to_number = Integer.toString(number);
int array[] = new int[to_number.length()];
for (i = 0; i < array.length; i++)
array[i] = to_number.charAt(i) - '0';
No need to call Integer.toString(number) multiple times.
Being N the number of digits in the parameter number (i.e., Integer.toString(number).length()) the time complexity can be calculated as follows:
String to_number = Integer.toString(number);
has a time complexity of N and the same for:
for (i = 0; i < array.length; i++)
array[i] = to_number.charAt(i) - '0';
The follow up double loop:
for (i = 0; i < array.length - 1; i++) {
for (j = 0; j < array.length - i - 1; j++) {
if (array[j] < array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
is a well-know for being N(N-1)/2, which can be simplified to a time complexity of O(N^2). The next loop
for (int k : array) {
strNum.append(k);
}
has time complexity of N. Finally,
int finalInt = Integer.parseInt(strNum.toString());
is also N. So the time complexity is N + N + N^2 + N + N, which simplifies to O(N^2) time complexity, also known as quadratic time complexity.
Now let us look at the space complexity:
int array[] = new int[Integer.toString(number).length()];
in this case N, and
for (int k : array) {
strNum.append(k);
}
also N, so the space complexity is 2N, which simplifies to O(N).

Pascal's triangle in Java [duplicate]

This question already has answers here:
Pascal's triangle positioning
(5 answers)
Closed 1 year ago.
Java beginner here! As part of practicing programming, I've run into Pascal's triangle. I tried to implement a solution where the triangle is printed like so:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
...
So roughly right-sided. My solution though runs into multiple errors, and although I would appreciate help with that, I would primarily like to know if I am thinking correctly with my solution. (For some functions I am using a custom library)
public static void main(String[] args) {
int input = readInt("Enter triangle size, n = ");
array = new int[input][input];
for (int i = 0; i < input; i++) { // rows
for (int j = 0; j < i + 1; j++) { // columns
if (i = 0) {
array[i][0] = 1;
} else if (i != 0 && i == j) {
array[i][j] = 1;
} else {
array[i][j] = array[i - 1][j] + array[i - 1][j - 1];
}
}
}
// print out only the lower triangle of the matrix
for (int i = 0; i < input; i++) {
for (int j = 0; j < input; j++) {
if (i <= j) {
System.out.println("%d ", array[i][j]);
}
}
}
}
You were on the right track. Here's how I implemented it:
Scanner sc = new Scanner(System.in);
System.out.print("Enter triangle size, n = ");
int n = sc.nextInt();
sc.close();
//This will be a jagged array
int[][] array = new int[n][0];
for (int i = 0; i < n; i++) {
//Add the next level (it's empty at the start)
array[i] = new int[i + 1];
for (int j = 0; j <= i; j++) {
//At the ends, it's just 1
if (j == 0 || j == i) {
array[i][j] = 1;
} else { //The middle
array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
}
}
}
for (int i = 0; i < n; i ++) {
for (int j = 0; j <= i; j++) {
//printf is what you use to do formatting
System.out.printf("%d ", array[i][j]);
}
//Without this, everything's on the same line
System.out.println();
}
Your else part was correct, but you didn't check if j equaled 0 before that. Instead of setting the current element to 1 when i was 0 or when i equaled j, you should have done it when j was 0 or when i equaled j. Because of this mistake, in later rows where i was not 0, but j was, you tried to access array[i - 1][j - 1], which was basically array[i - 1][-1], causing an IndexOutOfBoundsException.
I also made a jagged array instead of an even matrix because it made more sense that way, but it shouldn't matter much.
Also, this wasn't an error, but you did else if (i!=0 && i==j) The i != 0 part is unnecessary because you checked previously if i == 0.
Link to repl.it

Two player coin game : tracing optimal sequence in dynamic programming

Two players take turns choosing one of the outer coins. At the end we calculate the difference between the score two players get, given that they play optimally. for example the list{4,3,2,1},
the optimal sequence would be 4, 3, 2, 1. then i will get 4+2 = 6 scores and the opponent 4 scores.
Now i have developed an algorithm as follow:
My Job is to print the scores out, and also the optimal sequence in index. so in the array {4,3,2,1} the optimal sequence would be 0,1,2,3.
The maximum Runtime and Memory should not exceed n^2.
Therefore I implemented the above algorithm with bottom up approach,which means in an i*j table, according to my algorithm, subproblems are solved one by one until the only main problem, which locates at the top right corner(where i =0 and j = n-1). It works calculating the scores, but i have no idea how to trace the optimal sequence during runtime, since when I calculate subproblems by subproblems, only the score will be save and used in the next problem, while the sequence, which led to the final result, is hard to trace back.
I tried to create Pairs or multidimensional ArrayList to record the sequences and their corresponding memo[i][j]...... Well, they worked, but the memory needed would then be greater than n^2 and this is not allowed in my task.
So, does anymore have a better idea that does not require that much memory space?
Any help would be appreciated, cheers!
My code:
public int maxGain(int[] values) {
int n = values.length;
int [][] memo = new int[n][n];
for (int i = 0; i < n; i++)
memo[i][i] = values[i];
for (int i = 0, j = 1; j < n; i++, j++)
memo[i][j] = Math.max(values[i], values[j]);
for (int k = 2; k < n; k++) {
for (int i = 0, j = k; j < n; i++, j++) {
int a = values[i] + Math.min(memo[i + 2][j], memo[i + 1][j - 1]);
int b = values[j] + Math.min(memo[i + 1][j - 1], memo[i][j - 2]);
memo[i][j] = Math.max(a, b);
}
}
return memo[0][n - 1];
}
I guess your question is similar to Predict the Winner of LeetCode (486) with some minor changes that you would want to make:
Java
class Solution {
public boolean maxGain(int[] nums) {
int length = nums.length;
int[][] dp = new int[length][length];
for (int i = 0; i < length; i++)
dp[i][i] = nums[i];
for (int l = 1; l < length; l++)
for (int i = 0; i < length - l; i++) {
int j = i + l;
dp[i][j] = Math.max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]);
}
return dp[0][length - 1] > -1;
}
}
Python
class Solution:
def max_gain(self, nums):
length = len(nums)
memo = [[-1 for _ in range(length)] for _ in range(length)]
#functools.lru_cache(None)
def f():
def helper(nums, i, j):
if i > j:
return 0
if i == j:
return nums[i]
if memo[i][j] != -1:
return memo[i][j]
cur = max(nums[i] + min(helper(nums, i + 2, j), helper(nums, i + 1, j - 1)),
nums[j] + min(helper(nums, i, j - 2), helper(nums, i + 1, j - 1)))
memo[i][j] = cur
return cur
score = helper(nums, 0, length - 1)
total = sum(nums)
return 2 * score >= total
return f()
O(N) Memory
The space complexity might be an order of N for the second solution provided in this link:
class Solution {
public boolean maxGain(int[] nums) {
if (nums == null)
return true;
int length = nums.length;
int[] dp = new int[length];
for (int i = length - 1; i >= 0; i--) {
for (int j = i; j < length; j++) {
if (i == j)
dp[i] = nums[i];
else
dp[j] = Math.max(nums[i] - dp[j], nums[j] - dp[j - 1]);
}
}
return dp[length - 1] > -1;
}
}
Reference
Most optimal solutions are here in the discussion board

time complexities of java loops

How to find time complexities for the following loops.
1)
int I, j, k, n, mini, tmp;
for(i = 0; i< k; i++){
mini = i;
for(j =i +1; j < n; j++)
if (a[j] < a[mini])
mini = j;
tmp = a[i];
a[i] = a[mini];
a[mini] = tmp;
}
return a[k-1];
}
2)
void SelectionSort(int A[], int n) {
int i = 0;
while (i < n - 1) {
int j = i + 1;
while (j < n) {
if (A[j] < A[i])
swap(A[j], A[i])
j++;
}
i++;
}
}
Both are O(n^2) 1,2
In both, the outer loop runs from 0 to n (exclusive), and for each iteration - the inner loop runs from i+1 to n (exclusive).
If we sum the running time of the inner loops we get:
n- (0+1) + n- (1+1) + .... + n-(n-1 + 1) =
= n-1 + n-2 + .... + 0 =
0 + 1 + ... + n-1 = (*)
n(n-1)/2
which is in O(n^2)
The equation (*) comes from sum of aritmetic progression.
As a side note - both are sorting algorithms, the first is min sort and the second is as the function name says, selection sort.
(1) technically the first is O(k^2), but I assume it means the same here.
(2) Assuming the return a[k-1]; should be AFTER closing the scope of the outer loop, and its placement is a mistake. If it is not a mistake - the outer loop runs only once, and complexity is O(n).

Categories

Resources