两个排序数组中的第K个最小元素 - 错误

时间:2016-02-17 18:25:25

标签: java algorithm data-structures

我正在尝试实现该程序,以便在两个排序的数组中找到第k个最小元素。到目前为止,我提出了:

public static int kSmallest(int[] a, int[] b, int aStart, int aEnd,
      int bStart, int bEnd, int k) {
    int lena = aEnd - aStart + 1;
    int lenb = bEnd - bStart + 1;

    if (lena == 0) {
      return b[k - 1];
    }

    if (lenb == 0) {
      return a[k - 1];
    }

    if (k == 1) {
      return Math.min(a[aStart], b[bStart]);
    }

    if(lena + lenb == k){
        return Math.max(a[aEnd], b[bEnd]);
    }

    int i = lena / 2;
    int j = lenb / 2;

    int ma = a[i];
    int mb = b[j];

    if (i + j > k) {
      if (ma < mb) {
        return kSmallest(a, b, i + 1, aEnd, bStart, j - 1, k - i);
      } else {
        return kSmallest(a, b, aStart, i - 1, j + 1, bEnd, k - j);
      }
    } else {
      if (ma < mb) {
        return kSmallest(a, b, i + 1, aEnd, bStart, j - 1, k);
      } else {
        return kSmallest(a, b, aStart, i - 1, j + 1, bEnd, k);
      }
    }

  }

但它给出了错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
    at arrays.MedianArray.kSmallest(MedianArray.java:90)
    at arrays.MedianArray.kSmallest(MedianArray.java:117)
    at arrays.MedianArray.kSmallest(MedianArray.java:115)
    at arrays.MedianArray.kSmallest(MedianArray.java:115)
    at arrays.MedianArray.main(MedianArray.java:18)

有人可以告诉我程序中有什么问题吗?我正在获得索引超出约束的异常。

2 个答案:

答案 0 :(得分:0)

我不明白你想做什么,但我可以看到你总是减少你的k,lena,lenb。并且k的减速速度比lena和lenb快,因此当lena或lenb等于0时,k小于0.结果这些行:

if (lena == 0) {
  return b[k - 1];
}

if (lenb == 0) {
  return a[k - 1];
}

导致ArrayIndexOutOfBoundsException。

也许你应该尝试这样的事情:

public static int kSmallest(int[] a, int[] b, int aStart, int aEnd,
          int bStart, int bEnd, int k)
{
    int[] aa = new int[aEnd-aStart];
    java.lang.System.arraycopy(a, aStart, aa, 0, aa.length);

    int[] bb = new int[bEnd-bStart];
    java.lang.System.arraycopy(b, bStart, bb, 0, bb.length);

    if(k>aa.length || k>bb.length)
    {
        throw new ArrayIndexOutOfBoundsException();
    }

    return aa[k]<bb[k] ? aa[k] : bb[k];
}

答案 1 :(得分:0)

一些事情:

aStartbStart开始,不应该是这些情况:

if (lena == 0) {
  return b[bStart + k - 1];
}

if (lenb == 0) {
  return a[aStart + k - 1];
}

您还应该检查BOTH数组是否为空(lena == 0 && lenb == 0),否则您将尝试访问空数组的索引。

我确定这个块有问题:

if (i + j > k) {
  if (ma < mb) {
    return kSmallest(a, b, i + 1, aEnd, bStart, j - 1, k - i);
  } else {
    return kSmallest(a, b, aStart, i - 1, j + 1, bEnd, k - j);
  }
} else {
  if (ma < mb) {
    return kSmallest(a, b, i + 1, aEnd, bStart, j - 1, k);
  } else {
    return kSmallest(a, b, aStart, i - 1, j + 1, bEnd, k);
  }
}

使用a = [1,2,3,4,5,6]尝试b = [7,8,9,10,11,12]k = 2。你会期望得到2。第一个堆栈中的ij都是3,而mamb分别是410。您的代码将进入if (i + j > k)块,然后是if (ma < mb)块。然后它将搜索k-i最小的术语......但在这种情况下k-i为-1!出了点问题。

我建议你先写出你的病例的伪代码,并确保你明白你在每个场景中做了什么。然后你可以继续编码。