How to find the largest difference in change in an array? - java - java

Suppose I declare an array:
int[] arr = {10,2,7,11,3};
The largest (positive) change in this array would be 9 as 11 - 2 = 9.
How would I write a method that find the largest change in code with the smaller integer occurring earlier?
Thank you,

I rewrote the answer since I misunderstood the question.
The simplest but almost certainly not the most efficient way to do this is to check every change and comparing it to the previous one. If it is bigger, discard the previous one and remember this one instead.
int change = arr[1] - arr[0]; //give it an initial value, if we find a bigger change we will replace it
for(int i = 0; i < arr.length - 1; i++) {
for(int j = i + 1; i < arr.length; j++) {
if(arr[j]-arr[i] > change) {
change = arr[j]-arr[i];
}
}
}
This will still give an answer even if there are no positive changes. If you do not want that, you can modify it. It is trivial.
Keep in mind that arr.length - 1 is important in the outer loop.

Looks like you want to find the smallest number and the largest number in the list and comparing it with the largest number on the list.
List first item as minimum.
Compare to next item and if greater, assign that number as lesser.
List first item as largest.
Compare to next item and if smaller, assign that number as greater.
At the end of the list, you will have the least and the greatest number. The difference will be the difference between the smallest and the largest.
Hope that helps.

Interesting question! You could brute-force this pretty easily, as I'm still thinking for a more creative solution.
int [] arr = {5, 4, 3, 2, 1};
int biggestDifference = arr[1]-arr[0];
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if ((arr[j] - arr[i]) > biggestDifference) {
biggestDifference = arr[j] - arr[i];
}
}
}

Sorting the array would ensure that the smallest number will always be at the front and largest at the back.
public static void main(String []args){
int[] arr = {10,2,7,11,3};
int diff = findBiggestDiff(arr);
System.out.println(diff);
}
public static int findBiggestDiff(int[] arr){
Arrays.sort(arr);
int diff = arr[arr.length-1] - arr[0];
return diff;
}

Related

How to implement compareTo in a generic method that takes a generic array as argument?

I'm trying to implement a method, that, given a generic array, and two index values, slice the array, and find the largest element between the two given numbers.
<T extends Comparable<? super T>> T max(T[] array, int firstIndx, int secondIndx) { //requires comparable
T maxElement = array[0]; //8
System.out.println(Arrays.toString(array));
for (int i = firstIndx; i < secondIndx - 1; i++) {
for (int j = firstIndx + 1; j < secondIndx; j++) {
if (array[i].compareTo(array[j]) > 0) {
maxElement = array[i];
array[i] = array[j];
array[j] = maxElement;
}
}
}
System.out.println(Arrays.toString(array));
return maxElement;
}
But for an arrays of ints [8, 4, 6, 20, 1], is swapping correctly just the first two elements, giving me the wrong maximum elements. What's wrong with the code ?
There are two issues with your sort. The first is that you're using firstIndx and secondIndx, but based on how your code is structured, it's treating that second number as if it were the second index minus 1.
The second issue is that your inner loop is starting back at firstIndx every time, which breaks the bubble sort. It needs to start at i.
Try this modification to your for loops:
for (int i = firstIndx; i <= secondIndx - 1; i++) { // Notice the "<=".
for (int j = i + 1; j <= secondIndx; j++) { // j starts at i
// ... existing bubble sort code goes here
}
}
Edit: I failed to mention that your approach won't find the max if the max is already in its sorted position. You should just grab the max from array[secondIndx] after you're done sorting.
As an aside, firstIndx is a pretty bad variable name. It's only one letter more to write it out in full: firstIndex.

Maximum difference in an array

For this array {2,6,1,5,10,7} following code will return 10-1=9.Please explain how it works and how did this logic found the minimum value 1 in that array.
void method(int[] ar,int n) {
int max =ar[1]-ar[0];
int i,j;
for( i=0;i<n;i++)
{
for(j=i+1;j<n;j++){
if(ar[j]-ar[i]>max)
max=ar[j]-ar[i];
}
}
System.out.println(max);
}
You just need to find max number and min number within one loop :
int max = Integer.MIN_VALUE , min = Integer.MAX_VALUE;
for(int i = 0 ; i < n ; i ++){
max = Math.max(arr[i], max);
min = Math.min(arr[i], min);
}
System.out.println(max - min);
The logic makes an assumption that the maximum difference in the array is between the first two numbers.
Max variable is used to save the maximum difference
max = arr[1] - arr[0] //assumption made that the the first two integers give the max difference
Now we create a nested loop so that difference of a number is calculated with all other values in the array.
But we don't need to check the values that already have been computed to save our time. Since we only need the difference I would like to point out taht we take the difference as always positive. Hence we only take care of the values ahead as
abs(arr[0] - arr[1]) = abs(arr[1] - arr[0])
where abs represents the absolute value.
Now while comparing the difference of the one value with other values whenever the algorithm finds any difference that is greater than the maximum alue it updates the value of max.
So after exiting the loop we have the max difference in the array values.
PS: A better approach would be to sort the array and then subtract the index and the last value
PPS: If you want better understanding of this loop you can also look into Selection Sort
Try this.
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] a = { 2, 6, 1, 5, 10, 7 };
Arrays.sort(a);
System.out.println(a[a.length - 1] - a[0]);
}
}
The reason why it is getting '9' as answer is because the max difference that's being counted is 10-1=9.
Consider the loop when i=2 and j=4
The max difference that's counted is
=> max = ar[j] - ar[i];
=> max = 10 - 1;
=> max = 9
EDIT
But of course, a more optimal approach would be to sort the array and find the difference between first and last element.
Arrays.sort(ar);
System.out.println(ar[ar.length-1] - ar[0]);
Output
9
Code complexity is very high in your program.
There is always better way of doing it
mine is
int[] numArray = {2,6,1,5,10,7};
int max = numArray[0];
int min = numArray[0];
for( int i : numArray){
if( max < i )
max = i;
if( min > i )
min = i;
}
System.out.println("Maximum Difference of an Array is "+(max - min ));
This solution is used for not sorted array with negative numbers
public int computeDifference() {
int min_ele = arr[0];
int max_ele = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min_ele)
min_ele = arr[i];
if (arr[i]>max_ele)
max_ele = arr[i];
}
return Math.abs(max_ele - min_ele);
}

Java Recursion on an ArrayList

I have an ArrayList of int.
The main program - calls a method to get a list of the sum of all (n member) combination of the members of the list. Where n can be anywhere between 2 - 6. E.g. Original List is {1,2,3,4,5}; Then the output should be {6, 7, 8, 8, 9, 10, 9, 10, 11, 12} where n = 3;
I am looking for the optimum way to do this. Right now, the way I have written the program (which is working) is without recursion. I have methods for all numbers i.e.
MyMethod2 -- gives me all the sum of 2 member combinations of MyArrayList
MyMethod3 -- gives me all the sum of 3 member combinations of MyArrayList
MyMethod4 -- gives me all the sum of 4 member combinations of MyArrayList
......
So, you can see that there is a lot of duplicate set of codes.
Also the way the program has currently been written (e.g. My Method3):
MyMethod3
ArrayList<Integer> sum = new ArrayList<Integer>();
for (i = 0; i < MyArrayList.size(); i++){
for (j = i + 1; j < MyArrayList.size(); j++){
for (k = j + 1; k < MyArrayList.size(); k++){
int total = MyArrayList.get(i) + MyArrayList.get(j) + MyArrayList.get(k);
sum.add(total);
}
}
}
return sum;
The MyMethod for n = 6, can become pretty long. Also "n" can change in the future.
Is there a better way to do this using recursion to minimize duplicate code, and using the number n as a variablefor the method call. Is there a standard package in Java that can help with recursion.
Adding the Code based on #Maertin suggestion - which worked for me
ArrayList<Integer> myArray = new ArrayList<Integer>();
myArray.add(5);
myArray.add(6);
myArray.add(4);
myArray.add(2);
myArray.add(1);
ArrayList<Integer> finalSumArray = combineTwoArrayList(3, myArray, myArray);
public static ArrayList<Integer> combineTwoArrayList(int n, ArrayList<Integer> origArray, ArrayList<Integer> finalSumArray) {
if (n == 1) return finalSumArray;
ArrayList<Integer> finalSumArray = new ArrayList<Integer>();
for (int i = 0; i < sumArray.size() - 1; i++){
for (int j = i + 1; j < origArray.size(); j++){
finalSumArray.add(sumArray.get(i) + origArray.get(j));
}
}
--n;
return combineTwoArrayList(n, origArray, finalSumArray);
}
You are correct in wanting to do this via recursion, because now, instead of having three separate methods, you could have one method with a parameter n for n-member combinations.
public int nCombinationSum( int n, int i, ArrayList<Integer> arr, ArrayList<Integer> sumArr) {
/* Gets n-combination sums and puts into sumArr
Input: n consecutive element combination, current index i in arr, and output ArrayList
Output: Gets n consecutive element combinations in arr from index i to index (i + n) and puts into sumArr
*/
//**BASE CASE**
//if index out of arr bounds
if( i + n > arr.size() )
return 0;
//**RECURSIVE CASE**
else {
//sum of values in arr from i to (i + n)
int currComboSum = 0;
for( int j = 0; j < n; j++ )
currComboSum += arr.get(j);
//adding sum to next element in resultant array
sumArr.add( currComboSum );
return nCombinationSum( n, i + 1, arr, sumArr );
}
}
USAGE
In your main method, you can call nCombinationSum and provide it with the kind of combination (n), starting index (in your case, 0), and arrayList (arr), and the arrayList you want to append the sums in (sumArr).
This also has the potential added benefit of allowing you to add any n-combination sum starting from a certain index. If you would like, you could add an end index as well, but this is fairly extended as it is.
EDIT: Please edit your question to reflect that you want the result to be an arrayList of sums, rather than the total sum. It is not clear right now.
Basically, what you want to do with recursion, in general, is to set a base case and a recursive case.
Your base case would be if your index is out of bounds, because you're going to call all elements from index i to i + n.
For the recursive case, use the algorithm below to account for each element in arr, then just keep returning the function with the next index value, and the function will continue running until it is out of bounds.
Algorithm
Getting sum of n-combination elements
Appending that sum into resultant array sumArr
Feel free to refer to the code above for reference.
You can use recursion. Basically, you should have only two for loops. (which is the code for two member combinations). When you compute 'total', pass each 'total' value to an ArrayList MyArrayList2. Now for MyMethod3, you use the elements of MyArrayList2 and the original ArrayList and find new 'total' values again and pass that to MyArrayList3. For MyMethod4, you use the elements of MyArrayList3 and the original ArrayList and find new 'total' values again and pass that to MyArrayList4.... ....

Finding smallest element in an integer array in java using divide and conquor algorithm

I tried to find the smallest element in an integer array using what i understood about divide and conquor algorithm.
I am getting correct results.
But i am not sure if it is a conventional way of using divide and conquor algorithm.
If there is any other smarter way of implementing divide and conquor algorithm than what i have tried then please let me know it.
public static int smallest(int[] array){
int i = 0;
int array1[] = new int[array.length/2];
int array2[] = new int[array.length - (array.length/2)];
for(int index = 0; index < array.length/2 ; index++){
array1[index] = array[index];
}
for(int index = array.length/2; index < array.length; index++){
array2[i] = array[index];
i++;
}
if(array.length > 1){
if(smallest(array1) < smallest(array2)){
return smallest(array1);
}else{
return smallest(array2);
}
}
return array[0];
}
Your code is correct, but You can write less code using existing functions like Arrays.copyOfRange and Math.min
public static int smallest(int[] array) {
if (array.length == 1) {
return array[0];
}
int array1[] = Arrays.copyOfRange(array, 0, array.length / 2);
int array2[] = Arrays.copyOfRange(array, array.length / 2, array.length);
return Math.min(smallest(array1), smallest(array2));
}
Another point. Testing for the length == 1 at the beginning is more readable version. Functionally it is identical. From a performance point of view it creates less arrays, exiting as soon as possible from the smallest function.
It is also possible to use a different form of recursion where it is not necessary to create new arrays.
private static int smallest(int[] array, int from, int to) {
if (from == to) {
return array[from];
}
int middle = from + (to - from) / 2;
return Math.min(smallest(array, from, middle), smallest(array, middle + 1, to));
}
public static int smallest(int[] array){
return smallest(array, 0, array.length - 1);
}
This second version is more efficient because it doesn't creates new arrays.
I don't find any use in using a divide and conquer in this paticular program.
Anyhow you search for the whole array from 1 to N, but in two steps
1. 1 to N / 2
2. N / 2 + 1 to N
This is equivalent to 1 to N.
Also you program check for few additional checks after the loops which aren't actually required when you do it directly.
int min = a[0];
for(int i = 1; i < arr.length; i++)
if(min < a[i])
a[i] = min;
This is considered most efficient in finding out the minimum value.
When do I use divide and conquer
A divide and conquer algorithm works by recursively breaking down a problem into two or more sub-problems, until these become simple enough to be solved directly.
Consider the Merge Sort Algorithm.
Here, we divide the problem step by step untill we get smaller problem and then we combine them to sort them. In this case this is considered optimal. The normal runs in a O(n * n) and this runs in O(n log n).
But in finding the minimum the original has O(n). So this is good.
Divide And Conquer
The book
Data Structures and Algorithm Analysis in Java, 2nd edtition, Mark Allen Weiss
Says that a D&C algorithm should have two disjoint recursive calls. I.e like QuickSort. The above algorithm does not have this, even if it can be implemented recursively.
What you did here with code is correct. But there are more efficient ways of solving this code, of which i'm sure you're aware of.
Although divide and conquer algorithm can be applied to this problem, but it is more suited for complex data problem or to understand a difficult data problem by dividing it into smaller fragments. One prime example would be 'Tower of Hanoi'.
As far as your code is concerned, it is correct. Here's another copy of same code-
public class SmallestInteger {
public static void main(String[] args) {
int small ;
int array[] = {4,-2,8,3,56,34,67,84} ;
small = smallest(array) ;
System.out.println("The smallest integers is = " + small) ;
}
public static int smallest(int[] array) {
int array1[] = new int[array.length/2];
int array2[] = new int[array.length - (array.length/2)];
for (int index = 0; index < array.length/2 ; index++) {
array1[index] = array[index];
}
for (int index = array.length/2; index < array.length; index++) {
array2[index - array.length/2] = array[index] ;
}
if (array.length > 1) {
if(smallest(array1) < smallest(array2)) {
return smallest(array1) ;
}
else {
return smallest(array2) ;
}
}
return array[0] ;
}
}
Result came out to be-
The smallest integers is = -2

Averaging array values not coming out as expected, gives out of place value instead of correct one

I'm writing a program for a class at school, and when the independents couldn't help, I turn to you...
I encounter my issue when I attempt to find the average - the variables either don't add correctly or they don't divide correctly. For example, an input of [4], [2], [4], [2], will give me 7.0, when it should be 3.0. Similarly, [2], [2], [4], [4], will give 2.0.
As far as I'm aware, the rest of the code functions exactly as it should. I'm including only what should effect it, but I can post the rest if required.
public class ArrayFunctions
{
String elementNumber =
JOptionPane.showInputDialog("How many elements do you want?");
int number = Integer.parseInt(elementNumber);
//assigns how many elements are in the array, based on user input
int[] min_array = new int[number];
int recalculate = 0;
public void arrayValues()
{
for (int i = 1; i < (number + 1); i++)
{
String elementInfo =
JOptionPane.showInputDialog("Input value for element " + i);
int element = Integer.parseInt(elementInfo);
//assigns values for elements, based on user input
min_array[(i - 1)] = element;
}
System.out.println('\u000C'); /*using BlueJ, this clears the console*/
for (int i = 1; i < (number + 1); i++)
{
System.out.println(min_array[(i - 1)]);
}
//prints the values of the elements in the array
}
...
public double avg()
{
for (int i = 1; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[(i - 1)]);
}
//should add together the values of all the elements
//this may be where it stops working as intended
double array_avg = (recalculate / min_array.length);
return array_avg;
//should divide the sum of all the elements by how many elements there are
//this is the other place where it might stop working.
}
Again, I can post more code if required. Sorry about bad/lacking comments and poor structure at times, I need to get this written, because I've a due date for this. :/
for (int i = 1; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[(i - 1)]);
}
This loop is going between index 0 (1 - 1) and index min_array.length - 2 due to your boolean condition in the for loop, stating that it should go while i is LESS than the array's length, and then also subtracting it by 1 in the code.
A possible solution would be to simply go until it's less than OR equal to the size, or simply start your loop at 0 and stop the (i - 1) stuff in the average calculation.
for (int i = 0; i < min_array.length; i++)
{
recalculate += min_array[i];
}
Also, on a side note, you're basically making that same mistake in the GUI stuff as well above; I've corrected it (as well as kept your methodology of using 1-based indexing for asking the user to fill in values, rather than 0-based indexing)
for (int i = 0; i < number; i++){
String elementInfo =
JOptionPane.showInputDialog("Input value for element " + (i + 1));
int element = Integer.parseInt(elementInfo);
min_array[i] = element;
}
System.out.println('\u000C'); /*using BlueJ, this clears the console*/
for (int i = 0; i < number; i++){
System.out.println(min_array[i]);
}
I see that you're going from index 0 to index array.length - 2, instead of -1. That's the problem. I hope this helps
public double avg()
{
for (int i = 0; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[i]);
}
//should add together the values of all the elements
//this may be where it stops working as intended
double array_avg = (recalculate / min_array.length);
return array_avg;
//should divide the sum of all the elements by how many elements there are
//this is the other place where it might stop working.
}
Also always start a for loop with i=0 for counting purposes

Categories