【问题标题】:Find out if an array contains numbers within given range找出数组是否包含给定范围内的数字
【发布时间】:2014-11-04 01:13:42
【问题描述】:

所以,如果一个排序整数数组包含大于I 但小于u 的数字,则我在实现一个返回true 的程序时遇到了问题,否则false

我已经确定快速排序算法将是对数组进行排序的好方法,因为我不知道用户将如何输入它 - 然后,我将排序后的数组提供给二进制搜索并找出是否该数组包含指定范围内的整数。 问题是,我似乎无法对此进行推理,因为它不是我想在这里找到的一个值,而是一个范围。 另外,如果可能的话,我想递归地实现它。

这是我目前所拥有的:

import java.util.Scanner;

class RangeBinarySearch {
    public static int[] quickSort(int[] unsortedArray, int left, int right) {
    int[] sortArray = unsortedArray;
    if (left >= right)
        return sortArray;

    int pivot = unsortedArray[(left + right) / 2];

    int i = left;
    int j = right;

    while (i <= j) {
        while (unsortedArray[i] < pivot)
            i++;
        while (unsortedArray[j] > pivot)
            j--;
        if (i <= j) {
            int temp = unsortedArray[i];
            unsortedArray[i] = unsortedArray[j];
            unsortedArray[j] = temp;
            i++;
            j--;
        }
    }

    if (left < j)
        quickSort(unsortedArray, left, j);
    if (right > i)
        quickSort(unsortedArray, i, right);

    return sortArray;
    }

    public static boolean withinRangeSorted(int[] sortedArray, int I, int u) {// This uses binary search

    int start = 0;
    int end = sortedArray.length - 1;
    int mid = sortedArray[(start + end) / 2];


        if (sortedArray[start] > u || sortedArray[end] < I)
            return false;
        else if (sortedArray[start] > I && sortedArray[end] < u)
            return true;

        else {
            // What to do here? I am stuck!

        }
    return false;
    }

    public static void main(String[] args) {
    int size;
    int inum;

    Scanner input = new Scanner(System.in);
    System.out.println("Enter the size of the array: ");
    size = input.nextInt();
    int[] unsortArray = new int[size];

    for (int i = 0; i < size; i++) {
        int c = i + 1;
        System.out.println("Enter element " + c + " to be added to the array: ");
        inum = input.nextInt();
        unsortArray[i] = inum;
    }

    int left = 0;
    int right = size - 1;

    int[] sortedArray = quickSort(unsortArray, left, right);
    int I; // greater than
    int u; // less than

    System.out.println("Enter range starting point: ");
    I = input.nextInt();
    System.out.println("Enter range end point: ");
    u = input.nextInt();

    boolean result = withinRangeSorted(sortedArray, I, u);
    System.out.println(result);
    }
}

问题是,我似乎不知道如何构造withinRangeSorted 方法。

如果我正在搜索大于I 且小于u 的值,我主要对方法应该采用什么样的参数感到困惑。 我觉得我在这里走在正确的轨道上,但我似乎无法正确地制定递归。

任何帮助将不胜感激。

【问题讨论】:

  • 我没有得到任务,如果 i 和 u 之间存在一个数字,你应该返回 true 吗?还是每个数字都需要在这个范围内?
  • Iu 作为边界对我来说比 lu 更有意义。如果数组开始排序,我可能会对l 进行二进制搜索,并检查是否有下一个更高的值以及它与u 的比较情况。 (但是,“没有什么比 2u”)

标签: java algorithm recursion range binary-search


【解决方案1】:

您只需要在二分搜索期间根据您的范围检查调整数组边界。我很确定这些参数是l(下)和u(上)。请注意,我始终将范围视为包含-排除。

/**
 * Whether array has at least one element x such that l <= x < u.
 */
boolean withinRangeSorted (int[] array, int l, int u) {
    int start = 0;
    int end = array.length;
    while (start < end) {
        int current = (start + end) / 2;
        if (array[current] >= u) {
            end = current;
        } else if (array[current] < l) {
            start = current + 1;
        } else {
            return true;
        }
    }
    return false;
}

如果要将其转换为递归实现,请使用 startend 作为递归助手的参数。如果您不希望该范围具有包容性和排斥性,请调整&lt;&lt;= 等和+ 1,但检查是否存在逐个错误。

【讨论】:

    【解决方案2】:

    据我了解,数组中的所有整数都必须大于i,但小于u。所以实现很简单:

    boolean withinRange(int[] array, int lower, int upper) {
    
        for (int i : array)
            if (i <= lower && i >= upper)
                return false;
        return true;
    }
    

    我不确定为什么需要对数组进行排序,除非条件是该范围内需要至少 1 个数字,而不是我理解的所有数字。

    但是如果你真的需要找出它是否包含指定范围内的数字,那么你可以使用这个简单的方法来测试范围内的每个数字是否存在于数组中:

    boolean containsNumberInRange(int[] array, int lower, int upper) {
    
        for (int i = lower + 1; i < upper; i++)
            if (Arrays.binarySearch(array, i) >= 0)
                return true;
        return false;
    }
    

    顺便说一句,您不需要自己实现快速排序算法,除非它是家庭作业的一部分,因为可以使用 Arrays.sort(int[]) 代替内部使用快速排序。

    【讨论】:

    • 二分查找部分不是最优的。 Arrays.binarySearch(array, lower) 已经返回后继,所以你只需要检查它是否小于upper。你检查存在的方式也是错误的,from how I read the docs你应该检查&gt;= 0
    • 感谢指正。我忘记了返回值包含“将被插入”信息。我不明白你说的第一部分是什么意思。
    • 一般来说,处理一个排序的数组比处理一个未排序的数组要快得多——所以花在排序上的时间是值得的。有关详细信息,请参阅stackoverflow.com/questions/11227809/…
    • @AndersNK 我看不到在此处提供的 SO 帖子中类似分支的可能性。我在 Java 中对 100 万个整数的数组进行了尝试,但在时间上没有发现已排序数组和未排序数组之间有任何区别。事实上,如果我还考虑到排序开销,与使用未排序数组相比,它的效率非常低。
    • 我的意思是 int succ = Arrays.binarySearch(array, lower); return succ >= 0 ?数组[succ]
    【解决方案3】:

    您可以简单地尝试了解不同的可能性:

    // assuming ascending order   
    boolean isWithinRange (int [] sortedArray, int min, int max)
    {
        int minArr, maxArr;
    
        minArr = sortedArray [0];
    
        maxArr = sortedArray [sortedArray.length-1];
    
        // xxxx..[oooo].. OR  ..[oooo]..xxxx
        if (minArr > max || maxArr < min) return false;
    
        // ..xx[xxxx]xx..
        if (minArr >= min && maxArr <= max) return true;
    
        // ..xx[xxooo]..
        if (minArr >= min && minArr <= max) return true;
    
        // ..[oooxx]xx..
        if (maxArr >= min && maxArr <= max) return true;
    
        return false;
    }
    

    【讨论】:

      【解决方案4】:

      如果这样的查询很少,最好做完整的搜索。我们不需要对数组进行排序。 但是,如果有很多这样的查询并且我们想要有效地完成它们, 这个问题有一个简单的O(logn) 算法。 使用二分查找,我们可以找到第一个值为 >= u 的索引。 同样,通过进行另一次二分搜索,我们可以找到第一个索引 >= l。 如果两个索引相同,检查它 否则返回 true。

      【讨论】:

        猜你喜欢
        • 2010-12-09
        • 2020-11-25
        • 2013-05-12
        • 1970-01-01
        • 1970-01-01
        • 2022-10-14
        • 2022-01-20
        • 2017-11-01
        • 2020-04-27
        相关资源
        最近更新 更多