查找整数数组的平均值

Find average of an array of ints

给定任务

Return 整数数组的 "centered" 平均值,我们将其称为值的平均值,但忽略数组中的最大值和最小值。如果最小值有多个副本,则只忽略一个副本,对于最大值也是如此。使用 int 除法产生最终平均值。您可以假设数组的长度为 3 或更多。

centeredAverage([1, 2, 3, 4, 100]) → 3
centeredAverage([1, 1, 5, 5, 10, 8, 7]) → 5
centeredAverage([-10, -4, -2, -4, -2, 0]) → -3

我试图那样解决它,但我有点困惑(捕获 ArrayIndexOutOfBounds 异常):

public class Main {
    public static void main(String[] args) {
        int[] num = {1, 2, 3, 4, 100};
        int[] num1 = {1, 1, 5, 5, 10, 8, 7};
        int[] num2 = {-10, -4, -2, -4, -2, 0};
        System.out.println(centeredAverage(num));
        System.out.println(centeredAverage(num1));
        System.out.println(centeredAverage(num2));
    }

public static int centeredAverage(int[] nums) {
    int count = 0;
    int average = 0;
    //to search for max and min
    Arrays.sort(nums);
    //the last int of an array
    int end = nums[nums.length - 1];

    if (nums.length > 3) {
        //exclude minimum and maximum values
        for (int i = 1; i < end; i++) {
            if (!(nums[i] == nums[i + 1])) {
                count++;
                average = (nums[i] + nums[i + 1]) / count;
            }
        }
    }

    return average;
}

}

问题在于,您没有在末尾存储长度为 2 的值,而是在末尾存储了长度为 1 的值。 声明结束为:

int end = nums.length - 2;

我还注意到另一件事:

if (nums.length >= 3)

这应该有效:

public static int centeredAverage(int[] nums) {
//array to ArrayList
ArrayList<Integer> list = (ArrayList<Integer>)Arrays.stream(nums)     
                                .boxed()        
                                .collect(Collectors.toList());
//Sorting the ArrayList
Collections.sort(list);
//Removing first and last number
list.remove(0);
list.remove(list.size()-1);
//Returning the average
return (int) list.stream().mapToDouble(val -> val).average().orElse(0.0);
}

我会稍微扩展一下我对你的问题的评论:

您的解决方案是先对数组进行排序,然后跳过第一个和最后一个元素。想法不错,但实现是错误的:

  • int end = nums[nums.length - 1]; 应该是 int end = nums.length - 1 因为看起来你的意思是 end 是最后一个元素的索引
  • average = (nums[i] + nums[i + 1]) / count; 在循环中是错误的,因为你划分得太频繁了。该行也意味着您只添加 2 个元素并将其除以 count。这不是除最小和最大之外的所有数组元素的平均值。
  • if(nums.length > 3) 是不必要的,因为 "You may assume that the array is length 3 or more."(如果你想使用那个条件,它应该是 if if(nums.length >= 3)
  • if (!(nums[i] == nums[i + 1]))好像不对,为什么要跳过连续的相同值的元素呢?您已经跳过了第一个和最后一个元素。

您的代码应如下所示:

int sum= 0;
//to search for max and min
Arrays.sort(nums);
//the last int of an array
int end = nums.length - 1;


//exclude minimum and maximum values which are at index 0 and "end"
for (int i = 1; i < end; i++) {               
   sum += nums[i];
}

int average = sum / nums.length - 2;

您的方法的一个缺点是您正在更改传递的数组,因为排序是就地操作。因此,如果不应该发生这种情况,您至少必须复制数组。

您也根本不需要排序,只需跟踪最小和最高元素即可:

int smallest = Integer.MAX_VALUE;
int highest = Integer.MIN_VALUE;
int sum = 0;

for( int value : nums ) {
  sum += value;
  smallest = Math.min(smallest, value); //or use if(smallest > value) smallest = value;
  highest = Math.max(highest , value);  //or use if(highest < value) highest = value;
}

//smallest and highest are part of the sum so subtract them again
//since we ignore 2 elements we divide by length - 2
int average = (sum - smallest - highest) / (nums.length - 2);

现在我对 codingbat.com (https://codingbat.com/prob/p136585) 中相同问题的解决方案对于所有可能的组合都是正确的。详细答案如下:

public int centeredAverage(int[] nums) {
  //first find Min and Max
  int min=nums[0], max = nums[0];
  for(int i=1;i<nums.length;i++){
    min=Math.min(min,nums[i]);
    max=Math.max(max,nums[i]);
  }
      
  int total=0,count=0,mincount=0,maxcount=0;
  for(int i=0;i<nums.length;i++){
    //exclude min and max only once to total count
    if(nums[i]==min&&mincount==0) {
      mincount++;
        continue;
    }
    else if(nums[i]==max&&maxcount==0) {
      maxcount++;
        continue;
    }
    //find total excluding min and max number only once
    total+=nums[i];
    //also count the numbers included in total
    count++;
  }
    //return average
    return total/count;
}

1.Set 我们可能得到的 maxmin 值。 2.Let int total 计算数组中所有值的总和。 3.Set向上两个条件分别是nums[i]大于max,nums[i]小于min。如果满足条件,则将nums[i]的值赋给max/min。 4.Finally,从总和中减去最大值和最小值,计算平均值。

public int centerAverage(int[] nums)
int max= Integer.MIN_VALUE;
int min= Integer.MAX_VALUE;
int total=0;
for(int i=0;i<nums.length;i++){
 total+=nums[i];
 if(nums[i]>max){
  max=nums[i];
 }
 if(nums[i]<min){
  min=nums[i];
 }
}
return (total-max-min)/(nums.length-2);
}