Find all combinations in an array - java

I'm developing a game in Android Studio using Java, and I have some troubles with the method that does the counting of the score. Basically in the game I have an array of dices that have values from 1 to 6. Among these values I need to find how many times a special value appears.
Right now I have a method that makes it work fine for finding all single values (like all dices that have the value 5), and also if two dices add up to the special value (like 2 + 3, or 1 + 4). But it doesn't find the special value when there's more than two dices adding up to the number (like 1 + 1 + 3)
Example: If I have the dices with values [1, 2, 2, 2, 3, 5]
The result should be three "numberOfPairs" (1+2+2, 2+3, 5) and therefore the method should return 15, but for me it only returns 10.
I would really appreciate some ideas how to change this method to work better.
Here's the method I've been working on now:
public static int evaluatePoints(Dice dices[], int sumToReach) {
int values[] = new int[dices.length];
int numberOfPairs = 0;
int left = 0;
int right = values.length - 1;
for(int i = 0; i < dices.length; i++){
values[i] = dices[i].getValue();
if(values[i] == sumToReach){
numberOfPairs++;
values[i] = 0;
}
}
Arrays.sort(values);
while (values[right] > sumToReach + values[0]) {
right--;
}
while (left < right) {
if (values[left] + values[right] == sumToReach) {
numberOfPairs++;
left++;
right--;
}
else if(values[left] + values[right] < sumToReach) {
left++;
}
else right--;
}
return numberOfPairs*sumToReach;
}

Your question can be paraphrased as "Get all possible number representations as sum of other natural numbers". Here is pretty good solution.

Explanation of the Algorithm:
Suppose the input array is [1 2 2 2 3 5]
First the program will search for grpSize 6 i.e. 6 elements that sum upto sum of 5
Then the program will search for grpSize 5 i.e. 5 elements that sum upto sum of 5
.
.
.
then the program will search for grpSize 1 i.e. 1 element that sums upto sum of 5
If a set is found then elements will be removed from the resultList
Warning: This approach is recursive, may lead to stack overflow if number of dice increases manyfold
public static boolean func(int grpSize,int sum,int index,List<Integer> resultList,ArrayList<Integer> values) {
if(grpSize==1) {
int j;
for(j = index; j < resultList.size(); j++) {
if(resultList.get(j) == sum) {
values.add(resultList.get(j));
resultList.remove(j);
return true;
}
}
}
for(; index < resultList.size(); index++) {
if(func(grpSize-1, sum-resultList.get(index), index+1, resultList, values)) {
values.add(resultList.get(index));
resultList.remove(index);
return true;
}
}
return false;
}
public static void main(String[] args) {
List<Integer> resultList = new ArrayList<>();
ArrayList<ArrayList<Integer>> values = new ArrayList<>();
resultList.add(1);
resultList.add(2);
resultList.add(2);
resultList.add(2);
resultList.add(3);
resultList.add(5);
//3 2 2 2 3 5
int sum = 5;
int n = resultList.size();
for(int i = 0; i < n; i++) {
int k=i;
while(true) {
values.add(new ArrayList<>());
func(n-i, sum, 0, resultList, values.get(values.size() - 1));
if(values.get(k).isEmpty()) {
break;
} else {
k++;
}
}
}
values.removeIf(p -> p.isEmpty());
System.out.println("Number of pairs: "+values.size());
values.forEach((it) -> {
System.out.println(it);
});
int temp = 0;
for(int i = 0; i < values.size(); i++) {
for(int j = 0; j < values.get(i).size(); j++) {
temp += values.get(i).get(j);
}
}
System.out.println("sum: "+temp);
}
}
Working of recursive function:
This function requires
Group Size to search for
The sum to search for
The starting index which is always zero(could(should) be cleaned up)
The list of each die roll
The list to add found values
This is boolean function which will return true if a particular set if found to add up to THE SUM. The concept is that of basic Backtracking

Related

Java - counting most common elements

The task is to write a code which counts the most common number. For example A[1,2,4,4,4,5,6,7,4] would be 4 with 4 counts.
I need to keep this code simple because I just tried to implement my code from algorithm and data structure to java.
My idea was this but somehow I never reach the last condition.
public class countingNumbers{
public static void main(String []args){
System.out.print(counting(new int[]{1,1,1,2,3,4,4,4,4,5,6}));
}
public static int counting(int[] x){
int memory = 0;
int counter = 0;
int mostCommon = 0;
for(int i = 0; i < x.length-1;i++){
for(int j = i+1; j < x.length-1; j++){
if(x[i] == x[j]){
counter = counter +1;
}
else if(j == x.length-1 && counter >= memory){
mostCommon = x[i];
memory = counter;
counter = 0;
}
}
}
return mostCommon;
}
}
-> Thanks in advance for all your answers, I appreciate that. I'am just looking for the logic not for stream, api's or whatever.
I tried do handwrite the code and the implementation in java is only for myself to see if it worked out but unfortunately it doesn't.
Update - the right Solution is this:
public class countingNumbers{
public static void main(String []args){
System.out.print(counting(new int[]{1,2,2,2,6,2}));
}
public static int counting(int[] x){
int memory = 0;
int counter = 1;
int mostCommon = 0;
for(int i = 0; i < x.length;i++){
for(int j = i+1; j <= x.length-1; j++){
if(x[i] == x[j]){
counter = counter + 1;
}
if(j == x.length-1 && counter >= memory){
mostCommon = x[i];
memory = counter;
counter = 1;
}
}counter = 1;
} return memory;
}
}
I'd stream the array and collect it in to a map the counts the occurrences of each element, and then just return the one with the highest count:
/**
* #return the element that appears most in the array.
* If two or more elements appear the same number of times, one of them is returned.
* #throws IllegalArgumentException If the array is empty
*/
public static int counting(int[] x){
return Arrays.stream(x)
.boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElseThrow(() -> new IllegalArgumentException("x must not be empty"));
}
If you are good with stream api.. or just for educational goals there is stream solution with groupingBy:
Integer[] arr = {1, 1, 1, 2, 3, 4, 4, 4, 4, 5, 6};
Map<Integer, Long> map = Arrays.stream(arr)
.collect(Collectors.groupingBy(o -> o, Collectors.counting()));
Integer common = map.entrySet().stream()
.max(Comparator.comparingLong(Map.Entry::getValue))
.map(Map.Entry::getKey).get();
System.out.println(common);
Update: If stream is not relevant for you:
It can be done by foor-loop but still it's quite convenient to use Map here:
public static int counting(int[] x) {
Map<Integer, Long> map = new HashMap<>(); // key is a number, value is how often does it appear in the array
for (int number : x) {
if (map.get(number) != null) {
map.put(number, map.get(number) + 1);
} else {
map.put(number, 1L);
}
}
return Collections.max(map.entrySet(), Map.Entry.comparingByKey()).getKey();
}
Note: there are many ways to get key from map associated with max value. See here to find the most suitable way: Finding Key associated with max Value in a Java Map
Also if else statement can be replaced by merge method from java8:
map.merge(number, 1L, (a, b) -> a + b);
Take a look at these two lines:
for (int j = i + 1; j < x.length - 1; j++) {
and
} else if (j == x.length - 1 && counter >= memory)
You loop while j is strictly less than x.length - 1, but your else if only triggers when j is exactly equal to x.length - 1. So you can never hit the code in your else if block.
Also, your counter should really start at one, since you're counting the number of entries that match the one you're looking at, so you skip counting the first one. But since you're not outputting the counter anywhere, it's not terribly relevant I guess.
So to fix your code, change your inner for loop to go to j <= x.length - 1.
Declare two variables to hold the most common number and its frequency:
int mostCommon =Integer.MIN_VALUE;
int highFreq = 0;
Itereate over your array. For each element iterate over your array again and count its frequency. If current count is greater than highFreq update mostCommon by seting it to current element and set highFreq current count. Example:
public class countingNumbers{
public static void main(String[] args) {
int[] res = counting(new int[]{6, 4, 5, 4, 5, 6, 4, 3, 2});
System.out.println("most common number is: " + res[0] + " with " + res[1] + " counts");
}
public static int[] counting(int[] x) {
int mostCommon = Integer.MIN_VALUE;
int highFreq = 0;
for (int i = 0; i < x.length; i++) {
int currFreq = 0;
for (int j = 0; j < x.length; j++) {
if (x[i] == x[j]) {
currFreq++;
}
}
if (highFreq < currFreq) {
highFreq = currFreq;
mostCommon = x[i];
}
}
return new int[]{mostCommon, highFreq};
}
}

Java sorting array positive ascending to negative ascending

I can't solve the problem , where I need output from array A like {1,2,3,4,-1,-2,-3,-4}
from random numbers in array, then write it to another array B. So far my experimental code doesn't work as I'd
public static void main(String[] args) {
int a[] = {5,4,3,2,1,-3,-2,-30};
int length = a.length - 1;
for (int i = 0 ; i < length ; i++) {
for (int j = 0 ; j < length-i ; j++) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
}
for (int x : a) {
System.out.print(x+" ");
}
}
Output is 5 4 3 2 1 -2 -3 -30 , but I need 1,2,3,4,5,-2,-3,-30
Update:
public static void main(String[] args) {
int a[] = {5,4,3,2,1,-3,-2,-30,-1,-15,8};
int length = a.length - 1;
for (int i = 0 ; i < length ; i++) {
for (int j = 0 ; j < length-i ; j++) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
} else {
if (a[j] > a[j+1] && a[j+1] > 0) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
}
}
for (int x : a) {
System.out.print(x+" ");
}
}
I got closer to my target but 8 1 2 3 4 5 -1 -2 -3 -15 -30 , that number 8 ruins it all
Add an if-else to differentiate the positive and negative case.
if (a[j] < 0) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
} else {
if (a[j] > a[j+1] && a[j+1] > 0) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
If I understand you correctly you want to sort after two things. Positive numbers from low to high and negative numbers from high to low.
You could first sort from high to low and in a second run over the array skip all positives and then sort from high to low.
Does this help?
I could write some code, but I believe that's something you want to learn right now :)
Algo:
Traverse the Array and Store positives in one and Negatives in another. O(i)
Sort the positives array in ascending order. O(mLog(m))
Sort the negatives indescending order. O(nLog(n))
Create a final array of the size of the input.
Add all the positive array sorted values. Then add the negative array sorted values. O(i)
Total : O(i) + O(mLog(m)) + O(nLog(n)) + O(i) = O(mLog(m)) if m > n
I have used library functions here. But if you want you can the write the functions using the same idea.
public class PostivieAsendingNegativeDesending implements Comparator<Integer> {
public static void main(String args[]) {
int fullList[] = {5, 4, 3, 2, 1, -3, -2, -30};
ArrayList<Integer> subList = new ArrayList<>();
ArrayList<Integer> subList2 = new ArrayList<>();
for (int i = 0; i < fullList.length; i++) {
if (fullList[i] < 0) {
subList2.add((fullList[i]));
} else {
subList.add(fullList[i]);
}
}
Collections.sort(subList);
Collections.sort(subList2, new PostivieAsendingNegativeDesending());
subList.addAll(subList2);
for (int i = 0; i < subList.size(); i++) {
System.out.print(subList.get(i) + " ");
}
System.out.println("");
}
#Override
public int compare(Integer n1, Integer n2) {
return n2 - n1;
}
}
This will do the trick which uses only basic loops
public static void main(String[] args) {
int a[] = { 5, 4, 3, 2, 1, -3, -2, -30 };
int length = a.length - 1;
int pos = 0, neg = 0;
// find total count of positive and negative numbers
for (int i = 0; i <= length; i++) {
if (a[i] < 0)
neg++;
else
pos++;
}
// initialize the arrays based on 'pos' and 'neg'
int posArr[] = new int[pos];
int negArr[] = new int[neg];
// store pos and neg values in the arrays
int countPos = 0, countNeg = 0;
for (int i = 0; i <= length; i++) {
if (a[i] < 0) {
negArr[countNeg] = a[i];
countNeg++;
} else {
posArr[countPos] = a[i];
countPos++;
}
}
// sort positive numbers
for (int i = 0; i < posArr.length - 1; i++) {
for (int j = 0; j < posArr.length - 1 - i; j++) {
if (posArr[j] > posArr[j + 1]) {
int swap = posArr[j];
posArr[j] = posArr[j + 1];
posArr[j + 1] = swap;
}
}
}
// sort negative numbers
for (int i = 0; i < negArr.length - 1; i++) {
for (int j = 0; j < negArr.length - 1 - i; j++) {
if (negArr[j] < negArr[j + 1]) {
int swap = negArr[j];
negArr[j] = negArr[j + 1];
negArr[j + 1] = swap;
}
}
}
// 1. print out posArr[] and then negArr[]
// or
// 2. merge them into another array and print
}
Logic is explained below :
Find total count of positive and negative numbers.
Create and store the positive and negative values in the respective arrays.
Sort positive array in ascending order.
Sort negative array in descending order.
Print out positive array followed by the negative array OR merge them into another and print.
I suggest another approach. You should try to formulate the rules to which the exact comparison must adhere.
Your requirement seem to have the following rules:
Positive numbers always come before negative numbers.
Positive numbers are ordered in ascending order.
Negative numbers are ordered in descending order. Yes, I said descending. Since higher numbers come before lower numbers, i.e. −2 is greater than −7.
Warning: you are using a nested for loop, which means that the process time will grow exponentially if the array becomes larger. The good news is: you don't need to nest a for loop into another for loop. I suggest writing a Comparator instead:
// The contract of Comparator's only method 'compare(i, j)' is that you
// return a negative value if i < j, a positive (nonzero) value if i > j and
// 0 if they are equal.
final Comparator<Integer> c = (i, j) -> { // I'm using a lambda expression,
// see footnote
// If i is positive and j is negative, then i must come first
if (i >= 0 && j < 0) {
return -1;
}
// If i is negative and j is positive, then j must come first
else if (i < 0 && j >= 0) {
return 1;
}
// Else, we can just subtract i from j or j from i, depending of whether
// i is negative or positive
else {
return (i < 0 ? j - i : i - j);
}
}
Your code could look like this:
int[] a = { 5, 4, 3, 2, 1, -3, -2, -30 };
int[] yourSortedIntArray = Arrays.stream(a)
.boxed()
.sorted(c) // Your Comparator, could also added inline, like
// .sorted((i, j) -> { ... })
.mapToInt(i -> i)
.toArray();
Lambda expressions are a new concept from Java 8. The Java Tutorials provide some valuable information.

Determine whether or not can an array of numbers can be divided into two arrays, with each array holding the same sum of numbers

Below is a code to determine whether or not can an array of numbers can be divided into two arrays, with each array holding the same sum of numbers.
for example: {1, 3 ,2, 6} can be divided into {6} and {1,2,3}, therefore return true
while {1,5,7} can't be divided into two, balanced array, therefore return false
public boolean canBalance(int[] nums) {
for (int i = 0; i < nums.length; i++) {
int sum = 0;
for (int j = 0; j < i; j++) sum += nums[j];
for (int j = i; j < nums.length; j++) sum -= nums[j];
if (sum == 0) return true;
}
return false;
}
it's an accepted answer for an exercise in codingbat, I don't understand this piece in particular:
for (int j = 0; j < i; j++) sum += nums[j];
for (int j = i; j < nums.length; j++) sum -= nums[j];
doesn't for iteration usually starts with { and ends with } ?
and how come if sum == 0 means it can be balanced?
I have tried noting it down on piece of paper with array of {1,3,2,6} and had sum of 26, which returns false, where it's obvious that {1,3,2,6} should return true.
I think I misread the code, I don't know which, though. Or maybe the algorithm is false, but it was accepted in codingbat
The two for-loops are for weighing the two parts of the array, to find the array balancing point of an array.
Think of it like this:
You have a empty balance scale, in the first iteration of the outer for loop, i is zero.
It comes to first for loop, here j is 0 and i is 0 i < j is false, so it doesn't enter the first for-loop and it goes into the second for-loop and subtracts all the numbers from sum.
From second iteration onwards of the outer for-loop, it starts entering the first for-loop and
starts adding the elements of the array one-by-one to the sum.
In pictures, it is like starting with an empty balance scale, adding all the elements into the second scale, and moving one by one element to the first scale, like this:
In the end, if the sum is zero, then the array can be balanced, so return true. If the sum isn't 0, it's unbalanced.
The values in the are balanced by the loops like this:
Iteration of outer for loop when i is 0
Loop 2 -> i(0) j(0) Subtract 1, sum is -1
Loop 2 -> i(0) j(1) Subtract 3, sum is -4
Loop 2 -> i(0) j(2) Subtract 2, sum is -6
Loop 2 -> i(0) j(3) Subtract 6, sum is -12
Iteration of outer for loop when i is 1
Loop 1 -> i(1) j(0) Add 1, sum is 1
Loop 2 -> i(1) j(1) Subtract 3, sum is -2
Loop 2 -> i(1) j(2) Subtract 2, sum is -4
Loop 2 -> i(1) j(3) Subtract 6, sum is -10
Iteration of outer for loop when i is 2
Loop 1 -> i(2) j(0) Add 1, sum is 1
Loop 1 -> i(2) j(1) Add 3, sum is 4
Loop 2 -> i(2) j(2) Subtract 2, sum is 2
Loop 2 -> i(2) j(3) Subtract 6, sum is -4
Iteration of outer for loop when i is 3
Loop 1 -> i(3) j(0) Add 1, sum is 1
Loop 1 -> i(3) j(1) Add 3, sum is 4
Loop 1 -> i(3) j(2) Add 2, sum is 6
Loop 2 -> i(3) j(3) Subtract 6, sum is 0
Final result is true, therefore the array can be balanced
Code:
public class Test {
public static void main(String[] args) {
int[] test = { 1, 3, 2, 6 };
System.out.println("\nFinal result is "+canBalance(test));
}
public static boolean canBalance(int[] nums) {
for (int i = 0; i < nums.length; i++) {
System.out.println("\nIteration of outer for loop when i is " + i);
int sum = 0;
for (int j = 0; j < i; j++){
sum += nums[j];
System.out.println("Loop 1 -> i(" +i + ") j("+j + ") Add "+nums[j] + ", sum is "+sum+" ");
}
for (int j = i; j < nums.length; j++){
sum -= nums[j];
System.out.println("Loop 2 -> i(" +i + ") j("+j + ") Subtract "+nums[j] + ", sum is "+sum+" ");
}
if (sum == 0)
return true;
}
return false;
}
}
If you want to allow shuffling between the elements of the array, you can use recursion as follows (comments are self-explanatory)
public class Test {
public static void main(String[] args) {
int[] original = { 10, 2, 24, 32 };
System.out.println(canDivideArray(original));
}
private static boolean canDivideArray(int[] originalArray) {
int total = 0;
for (int number : originalArray) {
total += number;
}
// check if sum == 2x for any value of x
if (total % 2 != 0) {
return false;
} else {
// sum of each half array should be x
total /= 2;
}
return isTotal(originalArray, originalArray.length, total);
}
private static boolean isTotal(int array[], int n, int total) {
// successful termination condition
if (total == 0) {
return true;
}
// unsuccessful termination when elements have finished but total is not reached
if (n == 0 && total != 0){
return false;
}
// When last element is greater than total
if (array[n - 1] > total)
return isTotal(array, n - 1, total);
//check if total can be obtained excluding the last element or including the last element
return isTotal(array, n - 1, total - array[n - 1]) || isTotal(array, n - 1, total);
}
}
If reordering of the elements of the array is not allowed, we just have to find the split point in the given array. The solution in the question does this by trying all possible split points and checking if the sum of the two parts is equal. It has effort that is quadratic in the length of the input array.
Note that it is easy to come up with solutions that have linear effort, for example the following snippet. It builds sums of the elements on the left side and on the right side of array, in each step the smaller sum is increased by adding an array element. This is repeated until the parts meet.
This assumes that the array does not contain any negative numbers.
public boolean canBalance(int[] nums) {
int sumL = 0, sumR = 0;
int l = -1, r = nums.length;
while (r - l > 1) {
if (sumL < sumR) {
sumL += nums[++l];
} else {
sumR += nums[--r];
}
}
return sumL == sumR;
}
This is a recursive solution to the problem, one non recursive solution could use a helper method to get the sum of indexes 0 to a current index in a for loop and another one could get the sum of all the elements from the same current index to the end, which works. Now if you wanted to get the elements into an array and compare the sum, first find the point (index) which marks the spilt where both side's sum are equal, then get a list and add the values before that index and another list to go after that index.
Here's mine (recursion), which only determines if there is a place to split the array so that the sum of the numbers on one side is equal to the sum of the numbers on the other side. Worry about indexOutOfBounds, which can easily happen in recursion, a slight mistake could prove fatal and yield a lot of exceptions and errors.
public boolean canBalance(int[] nums) {
return (nums.length <= 1) ? false : canBalanceRecur(nums, 0);
}
public boolean canBalanceRecur(int[] nums, int index){ //recursive version
if(index == nums.length - 1 && recurSumBeforeIndex(nums, 0, index)
!= sumAfterIndex(nums, index)){ //if we get here and its still bad
return false;
}
if(recurSumBeforeIndex(nums, 0, index + 1) == sumAfterIndex(nums, index + 1)){
return true;
}
return canBalanceRecur(nums, index + 1); //move the index up
}
public int recurSumBeforeIndex(int[] nums, int start, int index){
return (start == index - 1 && start < nums.length)
? nums[start]
: nums[start] + recurSumBeforeIndex(nums, start + 1, index);
}
public int sumAfterIndex(int[] nums, int startIndex){
return (startIndex == nums.length - 1)
? nums[nums.length - 1]
: nums[startIndex] + sumAfterIndex(nums, startIndex + 1);
}
//non recursively
public boolean canBalance(int[] nums) {
for(int a = 0; a < nums.length; a++) {
int leftSum = 0;
int rightSum = 0;
for(int b = 0; b < a; b++) {
leftSum += nums[b];
}
for(int c = a; c < nums.length; c++) {
rightSum += nums[c];
}
if(leftSum == rightSum) {
return true;
}
}
return false;
}
I guess 'dividing' in the original question does not allow re-ordering of the array. So, you simply break the array at a particular position, and we will have the left side and the right side of the array. Numbers in each side should have the same sum.
The index (i) of outer loop is the breaking position.
for (int i = 0; i < nums.length; i++) {
The first inner loop sums the left side of the array.
for (int j = 0; j < i; j++) sum += nums[j];
The second inner loop subtracts elements of the right side from the sum of the left array.
for (int j = i; j < nums.length; j++) sum -= nums[j];
If the final result is zero, it means the sum of left side and right side is the same.
Otherwise, continue the outer loop and examine other breaking position until we find the right breaking position.
Approaching this problem with DP solution.
//Create a 2D array and fill in bottom up manner
//DP[totalsum / 2 + 1] [ length of array + ]
bool divisible(int arr[], int size)
{
int sum = 0;
// Determine the sum
for (i = 0; i < size; i++) sum += arr[i];
if (sum%2 != 0) return false;
bool DP[sum/2+1][size+1];
// initialize top row as true
for (i = 0; i <= size; i++)
DP[0][i] = true;
// initialize leftmost column, except DP[0][0], as 0
for (i = 1; i <= sum/2; i++)
DP[i][0] = false;
// Fill the partition table in botton up manner
for (int i = 1; i <= sum/2; i++)
{
for (int j = 1; j <= size; j++)
{
DP[i][j] = DP[i][j-1];
if (i >= arr[j-1])
DP[i][j] = DP[i][j] || DP[i - arr[j-1]][j-1];
}
}
return DP[sum/2][size];
}
Just as #Alvin Bunk said in the comment, the answer you give in the question itself is not a good answer, it works differently even if the order of elements is changed in the array.
You should check this wiki for the theory & implement it: http://en.wikipedia.org/wiki/Partition_problem
I wrote a standalone method to sum parts of an array and used this in my solution to get the simplest method I can see possible. If anyone has any comments, please join in. I appreciate the comments.
//Create a method that gets the sum from start to the iteration before end.
public int sumArray (int[] nums, int start, int end)
{
//Create a sum int that tracks the sum.
int returnSum = 0;
//Add the values from start (inclusive) to end (exclusive). In other words i : [start, end)
for (int i = start; i < end; i++)
{
returnSum += nums[i];
}
return returnSum;
}
//This is our main class.
public boolean canBalance(int[] nums) {
//If nums has an actual value, we can work with it.
if (nums.length > 0)
{
//We check to see if there is a value that is equal by using the sumArray method.
for (int i = 0; i < nums.length; i++)
{
//If from [0,i) the value equals from [i, nums.length), we return true;
if (sumArray(nums, 0, i) == sumArray(nums, i, nums.length))
{
return true;
}
}
//If we finish the loop, and find nothing, we return false;
return false;
}
//If there is no value, we return false.
else
{
return false;
}
}
When there aren't any curly braces around around code after a for statement in Java, the very next line is the only line processed as part of the for statement. In this case, the for is like a function that calls the next line of code, which is a for statement that then calls the next line of code. So the first for calls the second for which evaluates to see if the two sides are the same, and if they aren't then it kicks back up to the second for which continues incrementing itself until it finishes and then it returns to the first for, which increments, and calls the second for... and so on. That code seems like it's partially broken, though, since it would have to have all numbers in numeric order, and it doesn't check anything in the middle.
For instance:
{1, 2, 3, 1} //evaluates to true because 1-1=0, although it should be false
{6, 2, 2, 3} //evaluates to true because 6-3-2=0, although it should be false
{2, 3, 4, 6} //evaluates to true because 2+3-6=0, although it should be false

How I can print largest sum in this Program?

package Message;
public class Example_R {
public static void main (String args[])
int n=1;
int input[]={1, 2, 1, 3, 4};
for (int j=0; j<=4; j++) {
int Add = 0;
for (int i=0; i<=4; i++) {
if (input[j] !=input[i]) {
Add+=input[i];
}
}
System.out.println(Add);
}
}
}
Output of This program is: 9 9 9 8 7 sum of all the other elements in the array that are not equal to the element.
Now I want to extend the program so I can print the Largest sum of any of it's element, (In this case 9 is the largest sum.) Do you have any suggestions? For this assignment I am restricted from using additional array, hashmap etc. not allowed. Arrays.sort(..)
Hint: use a variable that is holding "the largest sum reached so far". You will update it very time you compute a new sum.
You will need to find "how and when do I initialize this variable ?" and "how do I update it ?"
You probably want to create a separate method that you pass your "input[]" array to (left as an exercise). However when considering problems like this, first just consider how you would do it in english (or whatever your native language is). Write down that strategy (an "algorithm") and then implement that in Java.
public class Example_R {
public static void main(String args[]) {
int input[] = { 1, 2, 1, 3, 4 };
int largestSum = 0;
int currentSum;
for (int j = 0; j < input.length; j++) {
currentSum = 0;
for (int i = 0; i < input.length; i++) {
if (input[j] != input[i]) {
currentSum += input[i];
}
}
System.out.println("Sum of all values not equal to " + input[j]
+ " is: " + currentSum);
if (j == 0) {
largestSum = currentSum;
} else {
if (largestSum < currentSum) {
largestSum = currentSum;
}
}
}
System.out.println("The largest overall sum was " + largestSum);
}
}
You'll need a temporary variable to save the current highest number.
int temp = intArray[0]
for(int i : intArray)
{
if(i > temp)
temp = i;
}
Try this:
int n = 1,sum=0;
int[] input = { 1, 2, 1, 3, 4 };
for (int j = 0; j <= 4; j++){
int Add = 0;
for (int i = 0; i <= 4; i++){
if (input[j] != input[i])
Add += input[i];
}
if (sum < Add)
sum = Add;
}
After completing the second loop every time,the "sum" was updated if it is less than the current "add" value.
You can use variables of type Comparable and use the compareTo() method.
one.compareTo(two) will return > 0 if one > two
one.compareTo(two) will return < 0 if one < two
one.compareTo(two) will return 0 if one and two are equal
Go through the array, compare the current index with the previous index, and update a variable that holds the currentLargest value.

Sort an array by remainder of 4

I have an exercise in which I have to sort an array in the following way:
the numbers that divide 4 with no remainder will be the first in the array (e.g 4,8,12,16).
the numbers that divide 4 with remainder of 1 will be the second in the array (1,5,9).
the numbers that divide 4 with remainder of 2 will be the third in the array (2,6,10).
the numbers that divide 4 with remainder of 3 will be last in the array.
For example, the following array:
int []a={1,7,3,2,4,1,8,14}
will be:
4 8 1 1 2 14 3 7
the order within the groups does not matter.
I have found a solution which works on O(n) time complexity and O(1) space complexity.
However, it is ugly and moves on the array 3 times. I would want a more elegant solution.
This is my code:
int ptr=a.length-1; int temp=0, i=0;
while (i<ptr){
//move 3 remained to the end
if (a[i] % 4==3){
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
i=0;
while (i<ptr){
if (a[i]%4==2)
{
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
i=0;
while (i<ptr){
if (a[i]%4==1)
{
temp=a[ptr];
a[ptr]=a[i];
a[i]=temp;
ptr--;
}
else
i++;
}
Important to know:
I don't want time complexity worse than O(n), and space complexity worse than O(1).
Since O(3 * N) is O(N), you only need to loop through the array three times:
Move the elements e % 4 == 0 to the front, swapping elements along the way;
Move the elements e % 4 == 1 to the front, swapping elements along the way;
Move the elements e % 4 == 2 to the front, swapping elements along the way;
The elements that e % 4 == 3 will be at the end after this.
Example:
public static void main(String args[]) {
int[] a = { 1, 7, 3, 2, 4, 1, 8, 14 , 9};
int current = 0;
for (int i = 0; i < 3; i++) {
for (int j = current; j < a.length; j++) {
if (a[j] % 4 == i) {
int b = a[j];
a[j] = a[current];
a[current] = b;
current++;
}
}
}
System.out.println(Arrays.toString(a));
}
Just use a comparator and make use for the very efficient internal sort algorithm.
Arrays.sort(a, new Comparator() {
public int compare(int a, int b) {
if(a%4 == b%4) {
if(a < b) return -1;
if(a > b) return 1;
return 0;
} else {
if(a%4 < b%4) return -1;
if(a%4 > b%4) return 1;
return 0;
}
}
});
You can use up more memory. This is not correct, but I will still put it.
int modulusLength = 4;
List<Integer> array[] = new List<Integer>[modulusLength];
for(int i = 0; i < modulusLength; i++)
array[i] = new ArrayList<Integer>;
for(int i = 0 ; i < a.length; i++)
array[a[i]%modulusLength].put(a[i]);
int counter = 0;
for(int i = 0 ; i < array.length; i++)
for(int j = 0; j < array[i].size; j++)
{
a[counter] = array[i].get(j);
counter++;
}
Horrible and scary, but was fun to write. And it works :)

Categories

Resources