繁体   English   中英

具有类返回类型的方法

[英]A method that has a class return type

我不太明白我将如何实现和解决这个问题:

考虑一个按排序顺序排列的 n 个数值的数组数据和一个数值目标值列表(目标值不一定要排序)。 您的目标是计算包含所有目标值的最小数组索引范围。 如果目标值小于 data[0],则范围应从 -1 开始。 如果目标值大于 data[n - 1],则范围应以 n 结尾。

例如,给定数组 [ 5 8 10 13 15 20 22 26] 和目标值 (8, 2, 9, 17),范围是 -1 到 5。

  1. 设计一个有效的算法来解决这个问题并在

    public static <T extends Comparable<? super T>> Interval findInterval(T[] sortedData, List<T> targetValues)

    其中Interval是一个类,它提供了两个公共方法getLower()getUpper()来返回Interval对象的下getUpper()和上getUpper() 实现Interval类。

我理解问题的算法。 但是,我很困惑我将如何实施它。 例如Interval findInterval方法的返回值是什么?

和“实现Interval类”。 我不明白getLower()getUpper()方法究竟应该返回什么或什么类型。

我希望有人能给我一个想法,我将如何实现这一点。

乍一看, Interval应该只是一个保存计算结果的数据结构。 因此, getLowergetUpper不会动态执行这些计算。

这种数据结构的一个例子可能是:

public final class Interval {
   private final int lower;
   private final int upper;

   public Interval(int lower, int upper) {
       // Check preconditions, like lower can't be < -1, etc.
       this.lower = lower;
       this.upper = upper;
   }

   public int getLower() { return lower; }
   public int getUpper() { return upper; }
}

我认为最有效的算法是O(log n + m)假设n排序数据和m目标值。

  1. 首先,您必须在tagetValues找到最低和最高值。 这可以在O(m)通过在循环所有元素时保持lowesthighest变量最新来完成。

  2. 然后,你可以做2个后续的二进制搜索sortedData找到从较低的指数lowest ,然后从最高指数highest 这将花费2 log n简化为O(log n)


完整实现示例

import java.util.List;
import java.util.Arrays;

public class FindInterval {
  public static void main(String[] args) {
    Integer[] data = new Integer[] {5, 8, 10, 13, 15, 20, 22, 26};
    List<Integer> targets = Arrays.asList(8, 2, 9, 17);
    
    Interval interval = findInterval(data, targets);
    
    System.out.println(interval);
  }
  
  public static <T extends Comparable<? super T>> Interval findInterval(
    T[] sortedData, 
    List<T> targetValues
  ) {
    if (targetValues.isEmpty()) {
      throw new IllegalArgumentException("'targetValues' must not be empty.");
    }
    
    List<T> targetBounds = findTargetBounds(targetValues);

    int lower = Arrays.binarySearch(sortedData, targetBounds.get(0));    
    if (lower < 0 && lower != -1) {
      lower = Math.abs(lower) - 2;
    }
    
    int upper = Arrays.binarySearch(sortedData, targetBounds.get(1));
    if (upper < 0) {
      upper = Math.abs(upper) - 1;
    }
    
    return Interval.of(lower, upper);
  }
  
  private static <T extends Comparable<? super T>> List<T> findTargetBounds(List<T> targetValues) {
    T lower = targetValues.get(0);
    T upper = targetValues.get(0);
    
    for (T value : targetValues) {
      if (value.compareTo(lower) == -1) lower = value;
      if (value.compareTo(upper) == 1) upper = value;
    }
    
    return Arrays.asList(lower, upper);
  }
  
  private final static class Interval {
    private final int lower;
    private final int upper;
    
    private Interval(int lower, int upper) {
      // Check preconditions, like lower can't be < -1, etc.
      this.lower = lower;
      this.upper = upper;
    }
    
    public int getLower() { return lower; }
    public int getUpper() { return upper; }
    
    @Override
    public String toString() {
      return "[" + lower + "," + upper + "]";
    }
    
    public static Interval of(int lower, int upper) {
      return new Interval(lower, upper);
    }
  }
    
}

据我所知, getLower()意味着返回较低的范围,而getUpper()意味着返回较高的范围。 因此,对于给出的示例: getLower() -> -1getUpper() -> 5

至于返回一个类,你可以简单地在你的方法中做这样的事情:

public static <T extends Comparable<? super T>>
Interval findInterval(T[] sortedData, List<T> targetValues) {
   ...
   return new Interval(...);
}

这回答了你的问题了吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM