Given an array of non-negative integers, find the largest multiple of 3 that can be formed from array elements.
For example, if the input array is {8, 1, 9}, the output should be "9 8 1", and if the input array is {8, 1, 7, 6, 0}, output should be "8 7 6 0".
Looking for code-review, best-practices and optimizations.
public final class DivThree {
private DivThree() {}
public static int divThree(int[] a) {
final Queue<Integer> queue0 = new LinkedList<Integer>(); // if num % 3 == 0, store num in queue0.
final Queue<Integer> queue1 = new LinkedList<Integer>(); // if num % 3 == 1, store num in queue1.
final Queue<Integer> queue2 = new LinkedList<Integer>(); // if num % 3 == 2, store num in queue2.
Arrays.sort(a);
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum = sum + a[i];
int remainder = a[i] % 3;
if (remainder == 0) {
queue0.add(a[i]);
} else if (remainder == 1) {
queue1.add(a[i]);
} else {
queue2.add(a[i]);
}
}
if (sum % 3 == 1) {
if (!queue1.isEmpty()) {
queue1.remove();
} else {
if (!queue2.isEmpty()) {
queue2.remove();
} else {
return -1;
}
if (!queue2.isEmpty()) {
queue2.remove();
} else {
return -1;
}
}
} else if (sum % 3 == 2) {
if (!queue2.isEmpty()) {
queue2.remove();
} else {
if (!queue1.isEmpty()) {
queue1.remove();
} else {
return -1;
}
if (!queue1.isEmpty()) {
queue1.remove();
} else {
return -1;
}
}
}
final List<Integer> list = new ArrayList<Integer>();
list.addAll(queue0);
list.addAll(queue1);
list.addAll(queue2);
Collections.sort(list);
int result = 0;
int pow = 1;
for (int i = 0; i < list.size(); i++) {
result = result + pow * list.get(i);
pow = pow * 10;
}
return result;
}
}
public class DivThreeTest {
@Test
public void test1() {
int[] a1 = {1, 2, 3, 4};
assertEquals(432, DivThree.divThree(a1));
}
@Test
public void test2() {
int a2[] = {8, 1, 7, 6, 0};
assertEquals(8760, DivThree.divThree(a2));
}
}
1.upto(a.size).flat_map { |n| a.permutation(n).map { |e| [e, e.map(&:to_s).join.to_i] } }.select { |_,n| n%3 == 0 }.max_by(&:last).first.map(&:to_s).join(' ') #=> "8 7 6 0"
. \$\endgroup\$