I try to solve Different Summands problem with greedy algorithm
Problem Description
Task. The goal of this problem is to represent a given positive integer π as a sum of as many pairwise
distinct positive integers as possible. That is, to find the maximum π
such that π
can be written as
π1 + π2 + Β· Β· Β· + ππ
where π1, . . . , ππ
are positive integers and ππ ΜΈ= ππ
for all 1 β€ π < π β€ π.
Input Format. The input consists of a single integer π.
Constraints. 1 β€ π β€ 10^9
.
Output Format. In the first line, output the maximum number π
such that π
can be represented as a sum
of π
pairwise distinct positive integers. In the second line, output π
pairwise distinct positive integers
that sum up to π
(if there are many such representations, output any of them).
My Code:
public class DifferentSummands {
private static List<Integer> optimalSummands(int n) {
List<Integer> summands = new ArrayList<Integer>();
int start = 1;
int newNumber = n;
if (n == 2) {
summands.add(2);
return summands;
}
while (true) {
if (summands.contains(newNumber - start)) {
start++;
continue;
} else {
newNumber -= start;
summands.add(start);
start++;
}
if (newNumber == 0) {
return summands;
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
List<Integer> summands = optimalSummands(n);
System.out.println(summands.size());
for (Integer summand : summands) {
System.out.print(summand + " ");
}
}
}
My code fails if the input was so big it takes about 3.24 seconds and the max time available is 1.5 seconds.
after testing my code I find out the problem wasn't only in code performance but there are mistakes it code also but using HashSet was really nice it match faster than ArrayList and this is my new code
My code
private static HashSet<Integer> optimalSummands(int n) {
HashSet<Integer> summands = new HashSet<>();
int start = 1;
int newNumber = n;
if (n == 2) {
summands.add(2);
return summands;
}
while (true) {
if (newNumber < 0) {
Object[] value = summands.toArray();
int secondlast = (int) value[summands.size() - 2];
int last = (int) value[summands.size() - 1];
summands.remove(last);
summands.remove(secondlast);
newNumber = secondlast + last -1;
}
if (summands.contains(newNumber - start) ) {
start++;
continue;
} else {
newNumber -= start;
summands.add(start);
start++;
}
if (newNumber == 0) {
return summands;
}
}
}