(剑指offer)面试题25. 快速找中位数

题目

中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数(或最中间两个数据的平均数). 给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)

思路

查找中位数问题可以转化为TOP k问题(即查找第k小的元素问题)。

  • 若数组长度为偶数,以数组{8,1,3,4,7,6}为例,则令 k = nums.length / 2,找到第k小的数(对应数组下标为k-1)和第k+1小(对应数组下标为k)的数4和6,取平均值,即是中位数。

  • 若数组长度为奇数,以数组{8,1,3,4,7}为例,则找到第k+1小(对应数组下标为k)的数4,即是中位数。

TOP问题:查找第k小的元素。可采用快排算法思想和冒泡排序算法思想。排序算法比较常见,不一一讲述。

代码

快排思想

 public static int FindMedium(int[] nums){
    if(nums.length % 2 == 0){
      return (findK2(nums.length / 2 -1,nums) +
          findK2(nums.length / 2,nums))/2;
    }else {
      return findK2(nums.length / 2,nums);
    }
  }

  /**
   * 找到第k+1小的数
   * 使用快排
   * @param nums 数组
   * @return
   */
  public static int findK2(int k,int[] nums){
    return quicksort(0,nums.length-1,nums,k);
  }

  public static int quicksort(int left,int right,int[] nums,int k){
    int mid = partion(left, right, nums);
    if(mid == k){
      return nums[mid];
    }
    else if(mid < k){
      return quicksort(mid+1, right, nums,k);
    }
    else {
      return quicksort(left, mid-1, nums,k);
    }
  }
  public static int partion(int left,int right,int[] nums){
    int l = left;
    int r = right;
    int midnum = nums[l];
    while (l<r){
      while (l<r && nums[r] >= midnum){
        r--;
      }
      nums[l] = nums[r];
      while (l<r && nums[l] <= midnum){
        l++;
      }
      nums[r] = nums[l];
    }
    nums[l] = midnum;
    return l;
  }

冒泡排序思想

 public static int FindMedium(int[] nums){
    if(nums.length % 2 == 0){
      return (findK1(nums.length / 2 -1,nums) +
          findK1(nums.length / 2,nums))/2;
    }else {
      return findK1(nums.length / 2,nums);
    }
  }

  /**
   * 找到第k+1小的数
   * 冒泡排序
   * @param nums 数组
   * @return
   */
  public static int findK1(int k,int[] nums){
    int len = nums.length;
    for(int i=0;i<=k;i++){
      for(int j=i+1;j<len;j++){
        if(nums[i] > nums[j]){
          int temp = nums[j];
          nums[j] = nums[i];
          nums[i] = temp;
        }
      }
    }
    return nums[k];
  }
展开阅读全文
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值