【问题标题】:Find the nearest/closest lower value of an element in a sorted 1D array在已排序的一维数组中查找元素的最近/最接近的较低值
【发布时间】:2018-01-10 21:22:06
【问题描述】:

我想知道是否有可能在非空排序数组中找到最接近的低元素,该元素可能存在或不存在。元素也可以重复任意次数。数组 +ve 的所有元素。

例如,如果我们有值 [2,5,6,7,7,8,9] 并且我们正在寻找最接近 6 的元素,它应该返回 5,因为 5 是数组,小于 6。 同样,如果我们要寻找最接近 9 的元素,它应该返回 8,因为 8 是数组中的最大数,小于 9。 如果没有找到最接近的较低元素,则返回 -1 就像我们正在寻找最接近 1 的元素一样,它应该返回 -1,因为没有这样的元素可以低于 1。这里 -1 表示在最靠近元素的数组中不存在这样的值

我已经尝试过下面的代码。没关系?如果我遗漏了什么,请帮助我。 Java 代码会更有帮助。

static int find(int[] a, int target)
{
    int n = a.length;

    if(target <= a[0])
        return -1;

    if(target > a[n-1])
        return a[n-1];

    int i=0,j=n,mid=0;

    while(i<j)
    {
        mid = (i+j)/2;
        if(target <= a[mid])
        {
            if( mid >0 & target> a[mid-1] )
            {   
                 return a[mid-1]; 
            }

            j= mid;
        }
        else
        {
            if( mid<(n-1) & target > a[mid+1] )
            {   
                 return a[mid+1]; 
            }

            i= mid+1;
        }
    }
    return mid;
}

【问题讨论】:

  • 空数组应该怎么办?那么数组中的负数呢--1 应该是什么意思呢?您的代码很难阅读,这就是我避免深入挖掘的原因。我建议至少投资于干净的语法。
  • 不,先生。全部 +ve no 并且应该至少有一个元素。这里 -1 表示最靠近元素的数组中不存在这样的值
  • @C-Otto 先生,我已经更新了您所需的信息。而且我也试图给出一个干净的语法。你现在能帮帮我吗?

标签: java arrays


【解决方案1】:

使用流:

import java.util.stream.IntStream;

public class FindNearestLowestValue {

    public final static void main(String[] args) {
        int[] array = {2,5,6,7,7,8,9};
        int searchVal = 6;
        // reverse the order so the first element of the filtered stream is the result
        System.out.println(
            IntStream.range(0, array.length)
                .map(i -> array[array.length - 1 - i])
                .filter(n -> n < searchVal)
                .findFirst().orElse(-1)
        );
    }
}

【讨论】:

  • 这不是“最接近的”,这是第一个较小的。
  • @M.Prokhorov 而 Sushovan 对所需功能的描述与此有何不同?尤其是这些例子正是我实现的。
  • 他说从[2, 5, 6, 8]的数组中,当寻找6时,算法应该返回5。你的做到了,但仅用于示例输入。如果我更改数组,您的算法就会中断。例如,给定[2, 6, 5, 3, 8],它将返回3。这是一个有效的例子,因为 OP 没有说数组是有序的。
  • @M.Prokhorov 根据标题,必须对数组进行排序。你的不是。一个未排序的数组也会破坏另一个答案,因为 binarySearch 也需要一个排序的数组
  • 哦,标题。没看标题。好的,那么您的解决方案很好,如果在性能方面有点偏重的话。
【解决方案2】:

存在一个标准的 binarySearch 函数。

static int find(int[] a, int target) {
    int position = Arrays.binarySearch(a, target);
    if (position >= 0) {
        System.out.println("Found at index " + position);
    } else {
        int insertIndex = ~position;
        System.out.println("Insert position at index " + insertIndex);
        position = insertIndex;
    }
    return position;
}

如果没有找到,它会提供插入位置的补码,如上所示。这意味着当结果为负时,找不到该项目。

它或多或少做了你所做的事情,但在没有找到时,它巧妙地返回一个负数:~插入位置(或 -insert 位置 - 1)。

/**
 * Search the next smaller array element.
 * @param a the array sorted in ascending order.
 * @param target the value to keep below.
 * @return the greatest smaller element, or -1.
 */
static int findNextSmaller(int[] a, int target) {
    int i= Arrays.binarySearch(a, target);
    if (i >= 0) {
        --i;
        while (i>= 0 && a[i] == target) {
            --i;
        }
    } else {
        i = ~i;
        --i;
    }
    return i == -1 ? -1 : a[i];
}

或者,因为int 是离散的:

static int findNextSmaller(int[] a, int target) {
    int i= Arrays.binarySearch(a, target - 1);
    if (i >= 0) {
        return target - 1;
    }
    i = ~i;
    --i;
    return i == -1 ? -1 : a[i];
}

【讨论】:

  • 感谢您的努力,先生。但是先生,我不需要在数组中查找元素。给定一个元素和一个非空 +ve 整数数组(其中给定的元素可能存在也可能不存在,并且元素可以重复任意次数),我需要在数组。
  • @Sushovan 我建议您阅读建议方法的 Javadoc,因为它描述了它如何处理缺失值。
  • 这个方法给出元素的索引>=搜索值。我会添加代码。
  • 像这样使用binarySearch的问题是假设数组已排序,但OP没有提到这一点,除了给出一个已排序的示例数组(但我会将其归因于自然对排序数据示例的人为偏见,而不是实际需求)。
  • @M.Prokhorov 查看我添加到答案中的评论。根据标题,数组确实需要排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 2015-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
相关资源
最近更新 更多