Why would my loop start at 1 rather than 0? - java

I am doing some exercises on codingbat because I have been struggling with arrays. The question was:
"Return the "centered" average of an array of ints, which we'll say is the mean average of the values, except ignoring the largest and smallest values in the array. If there are multiple copies of the smallest value, ignore just one copy, and likewise for the largest value. Use int division to produce the final average. You may assume that the array is length 3 or more."
I was able to code the solution correctly except for 1 part.
The correct code is:
public int centeredAverage(int[] nums) {
int max = nums[0];
int min = nums[0];
int add = nums[0];
for(int i = 1; i < nums.length; i++){
add += nums[i];
if(nums[i] > max){
max = nums[i];
}
else if(nums[i] < min){
min = nums[i];
}
}
return (add - max - min) / (nums.length - 2);
}
My question is why are we starting at int i = 1 rather than 0? If you start at 1 aren't you skipping over a cell?

The initialization:
int max = nums[0];
int min = nums[0];
int add = nums[0];
handles the case when i = 0 for you.

As you are setting max, min and add from zero index of array.By doing this u are finding min and max from a single loop iteration(i.e.. by compairing this values from the other elements of array). If u havn't done this then u have to use some other logic to find min and max of array like O(n)^2 soln.

Related

Finding max values of array 12 elements at a time

I have an array that has around 1000 entries, these are split up into 12 entries per year, I'm trying to find the maximum value for each year, to do so I need to read 12 values at a time and find the maximum value of those 12, and then move on to the next 12 values from the array, and so on until it is complete.
Trying to do this I made a temporary array to store the 12 values in, as well as the final array with the max score per year. The code below doesn't work and i'm unsure why, I have spent quite a while researching and attempting this with different solutions, any help will be appreciated :)
//double rain[]= new double [1268]; this is the array declared earlier with data in
double maxRAINyear[]= new double [1200];
double temp [] = new double [12];
int arrayCounter = 0;
int count = 0;
for (int c = 36; c < rain.length; c++) {
temp[count] = rain[c];
if (count == 12){
Arrays.sort(temp);
double max = temp[temp.length - 1];
maxRAINyear[arrayCounter] = max;
arrayCounter++;
count = 0;
}
count++;
}
It's difficult to see what's wrong with your code without knowing what it produces, but in any case this isn't a great way to do this.
I'll assume that you are constrained to the input format of one long array, even though a multidimensional array might make more sense depending on what else it's used for.
// double rain[] = new double[1268]; // input
double maxRAINyear[] = new double[(rain.length+11) / 12];
double max = Double.NEGATIVE_INFINITY;
for (int i = 0; i < rain.length; i++)
{
if (rain[i] > max) max = rain[i];
if (i % 12 == 0)
{
maxRAINyear[i / 12] = max;
max = Double.NEGATIVE_INFINITY;
}
}
if (rain.length % 12 != 0) maxRAINyear[maxRAINyear.length-1] = max;
This calculates the maximum of each 12 numbers as it goes, rather than storing them separately and sorting them. I've assumed there are a whole number of years stored. If you want to account for a partial year at the end this will need to be modified.
I implemented it without a temporary array, but by just iterating over the array. That should be more efficient.
int amountOfYears = rain.length/12-3;
double maxRAINyear[]= new double [amountOfYears];
for(int i=0;i<amountOfYears;i++){
//Find maximum for these 12 indixes
double max = Double.NEGATIVE_INFINITY;
for(int j=12*i+36;j<12*(i+1)+36;j++){ //use 12*i as an offset, that way, you don't need a temp array
if(rain[j] > max)
max = rain[j];
}
//store maximum
maxRAINyear[i] = max;
}
If you also need to find the partial year, use this
int amountOfYears = Math.ceil(rain.length/12f)-3;
double maxRAINyear[]= new double [amountOfYears];
for(int i=0;i<amountOfYears;i++){
//Find maximum for these 12 indixes
double max = Double.NEGATIVE_INFINITY;
int start = 12*i+36;
int end = Math.min(rain.length,12*(i+1)+36);
for(int j=start;j<end;j++){ //use 12*i as an offset, that way, you don't need a temp array
if(rain[j] > max)
max = rain[j];
}
//store maximum
maxRAINyear[i] = max;
}
When count is 11, you are incrementing it to 12 and going into the next round of the loop. Now temp[count] = rain[c]; will attempt to store a value into index 12 of temp, but there are only 12 entries with indices 0 through 11. So I suspect you are getting an ArrayIndexOutOfBoundsException.
I believe you should move count++ before the if statement. This way a count of 12 will be reset to 0 before it creates any havoc.
This solution have the advantage to work if the array length is not a multiple of the range without doing to many check.
public static double[] read(double[] array, int range) {
double[] result = new double[array.length / range + (array.length % range > 0 ? 1 : 0 )]; //Just add one cell if the length is not a multiple of the range
double max = array[0];
int i = 1;
while (i < array.length) {
if (i % range == 0) { //Next range
result[i / range - 1] = max; //Save last
max = array[i]; //Get current
} else if (array[i] > max) {
max = array[i];
}
++i;
}
result[result.length - 1] = max; //for the last range
return result;
}

How do you find the max even sum from an array with using a number only once?

I am having a trivial problem of finding a max even sum from an array in java.
for ex:
In an array {1,2,3,4,5,6}
The max even sum should be 16(1+2+3+4+6) out of 6(1+2+3),10(1+2+3+4) and 16.
But as of now,I am getting 10 as an output,because it is taking sum as an contiguous sum.
Please help me with it.
Appreciate that you will do one of two things with the total sum of all elements in the array. If the total sum be even, you return that number, but if it be odd, then you will have to remove a number in order to make it even. Note that removing an even number will leave the remaining sum odd, so there is no point in removing an even number. But, since the total sum be odd, then there must be at least one odd number in the array.
So all you need to do if the total sum be odd is to iterate over the array and remove the smallest odd number. And there is guaranteed to be at least one odd number.
Here is an implementation:
public int findMaxEvenSum(int[] array) {
int total = 0;
for (int i=0; i < array.length; ++i) {
total += array[i];
}
if (total % 2 == 0) {
return total;
}
// otherwise iterate over the array and remove the smallest odd
// number from the sum
int lastOdd = 0;
for (int i=0; i < array.length; ++i) {
if (array[i] % 2 == 1 && (lastOdd == 0 || array[i] < lastOdd)) {
total += lastOdd;
total -= array[i];
lastOdd = array[i];
}
}
return total;
}

Smallest and second smallest in an array

I've looked at the answer posted here (finding smallest and second smallest number) but I cannot get my code to work.
Here is what I have.
public static void shortestTimes(int[] times){
int counter = 0;
int secondLowest = times[counter];
int min = times[counter];
for (counter = 0; counter < times.length; counter ++) {
if (times[counter] < min) {
secondLowest = min;
min = times[counter];
} else if (times[counter] < secondLowest) {
secondLowest = times[counter];
}
}
System.out.println("The fastest time was: " + min + ". And the second fastest was: " + secondLowest);
}
When I put in the input:
int[] values = {1, 3, 3, 2, 5};
longestTimes(values);
I get the output:
The fastest time was: 1. And the second fastest was: 1
Why is my second lowest number not getting changed?
Your second lowest value is not getting changed because from the beginning you are setting secondLowest to be equal to the value at values[0], which is your lowest value in the array. If I were you, I would initialize both min and secondLowest to Integer.MAX_VALUE. Then the algorithm would behave as expected
Firstly when you declare min and secondLowest I would check if times.length >= 2.
I would then assign them with:
min = times[0];
secondLowest = times[1];
The problem is with your declaration of secondLowest and the fact that they both start at the lowest value. You don't have any sort of check to see if min and secondLowest are referring to the same number within the array.
If the array is guaranteed to contain unique values this isn't an issue, but if not you should change around your search. Sorting the array would help too.

How do I modify findMin to find the minimum element without comparing the array elements (use findMax )

// Method for getting the maximum value
public static int findMax(int[] inputArray) {
int maxValue = inputArray[0];
for (int i = 1; i < inputArray.length; i++) {
if (inputArray[i] > maxValue) {
maxValue = inputArray[i];
}
}
return maxValue;
}
// Method for getting the minimum value
public static int findMin(int[] inputArray) {
int minValue = inputArray[0];
for (int i = 1; i < inputArray.length; i++) {
if (inputArray[i] < minValue) {
minValue = inputArray[i];
}
}
return minValue;
}
How do I modify findMin to find the minimum element without comparing the array elements (use findMax )?
Without further information about inputArray,
for example knowing about some specific ordering of the elements,
there's no better way to find the min / max element in a general order of randomly ordered elements without visiting each element once.
That's all your methods do now,
there are no wasted operations here.
The code is good as it is (after #rink.attendant.6 kindly reformatted properly).
My only suggestion for possible simplification is to use Java 8 streams:
return Arrays.stream(inputArray).parallel().min().get();
and
return Arrays.stream(inputArray).parallel().max().get();
It's possible that this could achieve better performance than straight iteration by parallel processing of sublists.
Another potential optimisation is to find both the min and max in a single operation:
IntSummaryStatistics stats = Arrays.stream(inputArray).summaryStatistics();
int min = stats.getMin();
int max = stats.getMax();

How would I find the index of the smallest value in an int array?

I'm fairly new to java so I would like to keep it simple, and I figure I would have to take the first value of the array then compare it to each following value and if the value is larger smaller than the first, replace the value with it, but I don't know how to get index from that.
For an unstructured, unsorted array the best you can do, assuming you are only going to find the minimum value once, is a simple iteration over all elements (O(n) complexity), like so:
public int findMinIdx(int[] numbers) {
if (numbers == null || numbers.length == 0) return -1; // Saves time for empty array
// As pointed out by ZouZou, you can save an iteration by assuming the first index is the smallest
int minVal = numbers[0] // Keeps a running count of the smallest value so far
int minIdx = 0; // Will store the index of minVal
for(int idx=1; idx<numbers.length; idx++) {
if(numbers[idx] < minVal) {
minVal = numbers[idx];
minIdx = idx;
}
}
return minIdx;
}
Also, in the case of a tie for minimum value, this method will return the index of the first case of that value it found. If you want it to be the last case, simply change numbers[idx] < minVal to numbers[idx] <= minVal.
Here is with Java 8
public static int findMinIdx(int[] numbers) {
OptionalInt minimun = IntStream.of(numbers).min();
return IntStream.of(numbers).boxed().collect(toList()).indexOf(minimun.getAsInt());
}
Never cared about run time optimization, was just looking for a solution!, this worked and this would help you too, finding the index of the lowest values in an array.
// array[] -> Received the array in question as an parameter
// index -> stores the index of the lowest value
// in for loop, i is important to complete all the comparison in the function
// When it finds a lower value between the two, it does not change the index
// When it finds a lower value it changes it's index to that index
// If array has same value more than once, it will provide index to that values last occurrence
// Correct me if you find anything not working in this example...
//...
private static int index_of_minimum_value(int[] array) {
int index = 0;
for (int i = 1; i < array.length; i++) {
if ((array[i - 1] < array[i]) && ([index] > array[i - 1])) index = i - 1;
else if (array[index] > array[i]) index = i;
}
return index;
}

Categories

Resources