Algorithm 使用divide&;征服-提高查找阵列中的最大值和最小值的时间复杂度

Algorithm 使用divide&;征服-提高查找阵列中的最大值和最小值的时间复杂度,algorithm,time-complexity,binary-search,divide-and-conquer,Algorithm,Time Complexity,Binary Search,Divide And Conquer,这就是我在采访中被问到的问题 找到数组的最小值和最大值的最佳时间复杂度是多少 我回答:O(n)。遍历数组,跟踪到目前为止找到的最大值和最小值。非常简单和直接 面试官问你能用分而治之的方法来改进它吗。我说可能不会。然后谈话继续进行,最后我被要求实施分而治之的方法 这是: public class MinMaxInArray { public static int[] findMinMax(int[] array, int i, int j){ // base cases

这就是我在采访中被问到的问题

找到数组的最小值和最大值的最佳时间复杂度是多少

我回答:O(n)。遍历数组,跟踪到目前为止找到的最大值和最小值。非常简单和直接

面试官问你能用分而治之的方法来改进它吗。我说可能不会。然后谈话继续进行,最后我被要求实施分而治之的方法

这是:

public class MinMaxInArray {
    public static int[] findMinMax(int[] array, int i, int j){
        // base cases
        int arrLen = j - i + 1;
        if (arrLen == 1)
            return new int[]{array[i], array[j]};    //j and i are the same

        if (arrLen == 2){
            int min = Math.min(array[i], array[j]);
            int max = Math.max(array[i], array[j])           
            return new int[]{min, max};
        }

        // actual divide and conquer        
        int mid = i + (j-i)/2;
        int[] leftMinMax = findMinMax(array, i, mid);
        int[] rightMinMax = findMinMax(array, mid+1, j);
        return new int[]{  Math.min(leftMinMax[0], rightMinMax[0]), Math.max(leftMinMax[1], rightMinMax[1])   };
    }

    public static void main(String[] args){
        int[] array = {20, 5, 7, 25, 30, 1, 9, 12};
        int[] minMax= findMinMax(array, 0, array.length - 1);           //minMax[0] = minimum value, minMax[1] = maximum value
        System.out.println("min = " + minMax[0] + ", max = " + minMax[1] );
    }

}
我相信这仍然是O(n),因为所有元素都是比较的。但是面试官坚持说是O(logn),并让我考虑一下。我想了很多,我确信这是O(n)。如果我是正确的,仅仅应用分而治之并不总是降低复杂性

请纠正我,如果我的理解,这个算法仍然是O(n)


谢谢你

你说得对。除非对数组进行排序,否则仍然必须检查每一半中的每个元素(以及重复出现时的每四分之一和每八分之一)

它可以是O(logn)的唯一方法是,如果您可以放弃每个递归级别的一半搜索空间(例如在排序列表中搜索特定值),那么唯一的方法就是对它进行排序

但是,当然,
min
max
操作变成了O(1),因为您只需要获取列表的第一个和最后一个元素,根本不需要搜索


现在可能是考官建议分而治之,将每个问题级别的不同部分分配给不同的执行引擎,以便它们可以并行运行。这是我能看到它给你O(logn)的唯一其他方式,但我看不到基于发布内容的真实证据表明这是事实,而且我认为它需要相当多的引擎。

确实,使用分而治之的时间复杂度来查找min和max是O(N)

但是使用“分而治之”可以在很大程度上减少比较的次数,如果数据量很大,这确实会减少时间

所以,如果n是2的幂,则分治方法进行3/2n-2比较。如果n不是2的幂,它会进行3/2n-2以上的比较。

我也同意“使用分治法求最小值,求最大值”是O(n)
因为在“分而治之”中 Divide--->取O(n),因为它将每个段分成更小的一段。
征服--->它可以是任何正在给出结果的函数。因此,时间复杂性将取决于征服所做的事情。和合并排序一样,合并部分需要日志(n)时间


在本例中,征服是一种持续的操作

问题本身(迭代/分治)与标题(二进制搜索)之间的联系是什么?考官可能还想到了无法放入内存的超大数据数组(比如在有限的内存设备上)然后,分而治之可能有助于避免过多的磁盘交换。