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

Java 两个排序数组中的第k个最小元素-错误,java,algorithm,data-structures,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个最小元素的程序。到目前为止,我提出了:

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);
      }
    }

  }

有人能告诉我我的程序出了什么问题吗?我得到了索引越界异常。

我不明白您想做什么,但正如我看到的,您总是减少k,lena,lenb。k的reduse速度比lena和lenb快,因此当lena或lenb等于0时,k小于0。因此,这些行:

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

if (lenb == 0) {
  return a[k - 1];
}
导致阵列索引边界外异常

也许你应该试试这样:

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];
}
public static int kSmallest(int[]a,int[]b,int aStart,int aEnd,
内部B开始,内部弯板,内部k)
{
int[]aa=新的int[aEnd aStart];
java.lang.System.arraycopy(a,aStart,aa,0,aa.length);
int[]bb=新int[bEnd bStart];
java.lang.System.arraycopy(b,bStart,bb,0,bb.length);
如果(k>aa.长度| | k>bb.长度)
{
将新的ArrayIndexOutOfBoundsException()抛出;
}

return aa[k]我不明白您想做什么,但正如我所看到的,您总是减少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];
}
导致阵列索引边界外异常

也许你应该试试这样:

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];
}
public static int kSmallest(int[]a,int[]b,int aStart,int aEnd,
内部B开始,内部弯板,内部k)
{
int[]aa=新的int[aEnd aStart];
java.lang.System.arraycopy(a,aStart,aa,0,aa.length);
int[]bb=新int[bEnd bStart];
java.lang.System.arraycopy(b,bStart,bb,0,bb.length);
如果(k>aa.长度| | k>bb.长度)
{
将新的ArrayIndexOutOfBoundsException()抛出;
}
返回aa[k]一些内容:

既然您是从
aStart
bStart
开始的,那么这些情况不应该是:

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

if (lenb == 0) {
  return a[aStart + k - 1];
}
您可能还应该检查两个数组是否都是空的
(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);
  }
}
if(i+j>k){
如果(ma
尝试
a=[1,2,3,4,5,6]
b=[7,8,9,10,11,12]
k=2
i
j
在第一个堆栈中都是
3
,而
ma
mb
将分别是
4
10
。您的代码将进入
if(i+j>k)
块,然后是
if(ma
block。然后它将搜索
k-i
th最小项…但是
k-i
在这种情况下是-1!有问题

我建议您首先为您的案例编写伪代码,并确保您了解在每个场景中所做的操作。然后您可以继续编写它。

一些事情:

既然您是从
aStart
bStart
开始的,那么这些情况不应该是:

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

if (lenb == 0) {
  return a[aStart + k - 1];
}
您可能还应该检查两个数组是否都是空的
(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);
  }
}
if(i+j>k){
如果(ma
尝试
a=[1,2,3,4,5,6]
b=[7,8,9,10,11,12]
k=2
i
j
在第一个堆栈中都是
3
,而
ma
mb
将分别是
4
10
。您的代码将进入
if(i+j>k)
块,然后是
if(ma
block。然后它将搜索
k-i
th最小项…但是
k-i
在这种情况下是-1!有问题

我建议您首先为您的案例编写伪代码,并确保您了解在每个场景中所做的工作,然后您可以继续编写代码