Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 整数数组的最大子数组 在一次采访中,我的一个朋友被要求找到一个最大的数组的子数组,这是我的问题的解决方案,我如何改进解决方案使它更优化,我应该考虑以递归的方式做吗?p> def get_max_sum_subset(x): max_subset_sum = 0 max_subset_i = 0 max_subset_j = 0 for i in range(0,len(x)+1): for j in range(i+1,len(x)+1): current_sum = sum(x[i:j]) if current_sum > max_subset_sum: max_subset_sum = current_sum max_subset_i = i max_subset_j = j return max_subset_sum,max_subset_i,max_subset_j_Algorithm - Fatal编程技术网

Algorithm 整数数组的最大子数组 在一次采访中,我的一个朋友被要求找到一个最大的数组的子数组,这是我的问题的解决方案,我如何改进解决方案使它更优化,我应该考虑以递归的方式做吗?p> def get_max_sum_subset(x): max_subset_sum = 0 max_subset_i = 0 max_subset_j = 0 for i in range(0,len(x)+1): for j in range(i+1,len(x)+1): current_sum = sum(x[i:j]) if current_sum > max_subset_sum: max_subset_sum = current_sum max_subset_i = i max_subset_j = j return max_subset_sum,max_subset_i,max_subset_j

Algorithm 整数数组的最大子数组 在一次采访中,我的一个朋友被要求找到一个最大的数组的子数组,这是我的问题的解决方案,我如何改进解决方案使它更优化,我应该考虑以递归的方式做吗?p> def get_max_sum_subset(x): max_subset_sum = 0 max_subset_i = 0 max_subset_j = 0 for i in range(0,len(x)+1): for j in range(i+1,len(x)+1): current_sum = sum(x[i:j]) if current_sum > max_subset_sum: max_subset_sum = current_sum max_subset_i = i max_subset_j = j return max_subset_sum,max_subset_i,max_subset_j,algorithm,Algorithm,通过考虑最大和子数组必须满足的条件,可以得出一种更好的解决方法:两端未包含的第一项(如果有)必须为负,两端包含的最后一项必须为非负。除了在原始数据中发生这些变化之外,您不需要考虑子阵列的任何其他端点。 下面是一个来自 除非我遗漏了一些重要的东西,如果它们是正整数,子集将包括整个数组,如果它们是整数,它将只包括正整数。还有其他限制吗?您的解决方案是O(n^2)。最优解是线性的。它的工作原理是从左到右扫描阵列,并记录最佳和和和当前和: def get_max_sum_subset(x): b

通过考虑最大和子数组必须满足的条件,可以得出一种更好的解决方法:两端未包含的第一项(如果有)必须为负,两端包含的最后一项必须为非负。除了在原始数据中发生这些变化之外,您不需要考虑子阵列的任何其他端点。 下面是一个来自


除非我遗漏了一些重要的东西,如果它们是正整数,子集将包括整个数组,如果它们是整数,它将只包括正整数。还有其他限制吗?

您的解决方案是O(n^2)。最优解是线性的。它的工作原理是从左到右扫描阵列,并记录最佳和和和当前和:

def get_max_sum_subset(x):
    bestSoFar = 0
    bestNow = 0
    bestStartIndexSoFar = -1
    bestStopIndexSoFar = -1
    bestStartIndexNow = -1
    for i in xrange(len(x)):
        value = bestNow + x[i]
        if value > 0:
            if bestNow == 0:
                bestStartIndexNow = i
            bestNow = value
        else:
            bestNow = 0

        if bestNow > bestSoFar:
            bestSoFar = bestNow
            bestStopIndexSoFar = i
            bestStartIndexSoFar = bestStartIndexNow

    return bestSoFar, bestStartIndexSoFar, bestStopIndexSoFar

在(强烈推荐)中也讨论了此问题。在那里你还可以找到一个递归的解决方案,它不是最优的(O(n logn)),但比O(n^2)要好。

n
-元素计数,
a(i)
-你的数组
f(i)
-在
i
位置结束的子数组的最大和(最小长度为1)。然后:


max(0,f(1),f(2),…,f(n-1))
-答案

这是一个众所周知的问题,显示了重叠的最优子结构,建议采用动态规划(DP)解决方案。虽然DP解决方案通常相当棘手(我认为至少如此!),但这是一个很好的例子,可以介绍整个概念

首先要注意的是,结束于位置j的最大子阵列(必须是给定阵列a的连续部分)要么由结束于位置j-1加上a[j]的最大子阵列组成,要么为空(仅当a[j]<0时才会发生这种情况)。换句话说,我们要问的是,元素A[j]是否对当前的最大和起到了积极的作用,该和在位置j-1处结束。如果是,则将其包含在迄今为止的最大子阵列中;如果没有,就不要。因此,通过解决重叠的较小子问题,我们可以建立最佳解决方案

然后,可以通过以下关系递归地给出终止于位置j的最大子阵列的和:

sum[0] = max(0, A[0])
sum[j] = max(0, sum[j-1] + A[j])
我们可以通过从左到右扫描a,以自下而上的方式建立这些答案。当我们考虑[j]时,我们更新和[j]。通过这个过程,我们还可以跟踪整体最大值和最大子阵列的位置。下面是我用Ruby编写的一个快速解决方案:

def max_subarray(a)
    sum = [0]
    max, head, tail = sum[0], -1, -1
    cur_head = 0

    (0...a.size).each do |j|
        # base case included below since sum[-1] = sum[0]
        sum[j] = [0, sum[j-1] + a[j]].max
        cur_head = j if sum[j-1] == 0
        if sum[j] > max
            max, head, tail = sum[j], cur_head, j
        end
    end

    return max, head, tail
end
如果你想自己测试一下,看看我的


这显然是一个线性O(N)算法,因为只需要通过列表一次。希望这有帮助

麻省理工学院有一段短片,帮助您理解这个动态编程问题。 单击“问题”部分下的第一个链接,您将看到它。

Java解决方案:

不适用于所有负片的数组

public static int[] maxsubarray(int[] array) {

    //empty array check

    if (array.length == 0){
        return new int[]{}; 
    }

    int max = 0;
    int maxsofar = 0;

    //indices 

    int maxsofarstart = 0;
    int maxsofarend = 0;
    int maxstartindex = 0;

    for (int i = 0; i < array.length; i++) {
        if (array[i] > 0) {

            if (max == 0) {
                maxstartindex = i;
            }

            max = max + array[i];

            if (max > maxsofar) {

                maxsofar = max;
                maxsofarstart = maxstartindex;
                maxsofarend = i;

            }

    } else {
        max = 0;
    }

}

return Arrays.copyOfRange(array, maxsofarstart, maxsofarend + 1);

}
公共静态int[]maxsubarray(int[]array){
//空数组检查
如果(array.length==0){
返回新的int[]{};
}
int max=0;
int maxsofar=0;
//指数
int maxsofarstart=0;
int maxsofarend=0;
int maxstartindex=0;
for(int i=0;i0){
如果(最大==0){
maxstartindex=i;
}
max=max+array[i];
如果(最大值>最大值){
最大值=最大值;
maxsofarstart=maxstartindex;
maxsofarend=i;
}
}否则{
max=0;
}
}
返回数组.copyOfRange(数组,maxsofarstart,maxsofarend+1);
}

这是一个解释得最清楚、测试得最有效的解决方案-

package me.rerun;
公共级卡丹{
公共静态void main(字符串[]args){
int[]intArr={3,-1,-1,-1,2,0,0,0};
//int[]intArr={-1,3,-5,4,6,-1,2,-7,13,-3};
//int[]intArr={-6,-2,-3,-4,-1,-5};
FindMax子阵列(intArr);
}
公共静态无效findMaxSubArray(int[]输入阵列){
int maxStartIndex=0;
int maxEndIndex=0;
int maxSum=Integer.MIN_值;
int-cumulativeSum=0;
int maxStartIndexUntilNow=0;
对于(int currentIndex=0;currentIndex最大和){
maxSum=累积量;
maxStartIndex=maxStartIndexUntilNow;
maxEndIndex=currentIndex;
}

else if(cumulativeSum这是正确的Java代码,它将处理包括所有负数在内的场景

public static long[] leftToISumMaximize(int N, long[] D) {
    long[] result = new long[N];
    result[0] = D[0];
    long currMax = D[0];
    for (int i = 1; i < N; i++) {
        currMax = Math.max(D[i], currMax + D[i]);
        result[i] = Math.max(result[i - 1], currMax);
    }
    return result;
}
public static long[]leftToSummaximize(int N,long[]D){
long[]结果=新的long[N];
结果[0]=D[0];
长电流最大值=D[0];
对于(int i=1;i
我为一个更一般的问题创建了一个函数:

  • 查找最大和子数组(表示其边界和和,而不仅仅是和)
  • 如果两个子阵列的和相等,则选择较短的一个子阵列
  • 如果两个等长的子阵列具有相等的和,则选择第一个出现的子阵列
函数基于Kadane的算法,在O(n)时间内运行。基本上,就是这样:

function MaxSumSubarray(a, n, start out, len out)
    -- a - Array
    -- n - Length of the array
    -- start - On output starting position of largest subarray
    -- len - On output length of largest subarray
    -- Returns sum of the largest subarray
begin

    start = 0
    len = 1
    int sum = a[0]

    curStart = 0
    curLen = 1
    curSum = a[0]

    for i = 2 to n
        begin
            if a[i] >= curSum + a[i] then
                begin
                    curStart = i
                    curLen = 1
                    curSum = a[i]
                end
            else
                begin
                    curLen = curLen + 1
                    curSum = curSum + a[i]
                end

            if (curSum > sum) OR
               (curSum = sum AND curLen < len) OR
               (curSum = sum AND curLen = len AND curStart < start) then
               begin
                    start = curStart
                    len = curLen
                    sum = curSum
                end

        end

    return sum

end
函数MaxSum子阵列(a、n、起始输出、len输出)
--a-数组
--n-数组的长度
--开始-最大子阵列的输出开始位置
--len-关于最大子阵列的输出长度
--返回最大子数组的和
开始
开始=0
莱恩=
package me.rerun;

public class Kadane {

    public static void main(String[] args) {
        int[] intArr={3, -1, -1, -1, -1, -1, 2, 0, 0, 0 };
        //int[] intArr = {-1, 3, -5, 4, 6, -1, 2, -7, 13, -3};
        //int[] intArr={-6,-2,-3,-4,-1,-5,-5};
        findMaxSubArray(intArr);
    }



public static void findMaxSubArray(int[] inputArray){

    int maxStartIndex=0;
    int maxEndIndex=0;
    int maxSum = Integer.MIN_VALUE; 

    int cumulativeSum= 0;
    int maxStartIndexUntilNow=0;

    for (int currentIndex = 0; currentIndex < inputArray.length; currentIndex++) {

        int eachArrayItem = inputArray[currentIndex];

        cumulativeSum+=eachArrayItem;

        if(cumulativeSum>maxSum){
            maxSum = cumulativeSum;
            maxStartIndex=maxStartIndexUntilNow;
            maxEndIndex = currentIndex;
        }
        else if (cumulativeSum<0){
            maxStartIndexUntilNow=currentIndex+1;
            cumulativeSum=0;
        }
    }

    System.out.println("Max sum         : "+maxSum);
    System.out.println("Max start index : "+maxStartIndex);
    System.out.println("Max end index   : "+maxEndIndex);
}

}
public static long[] leftToISumMaximize(int N, long[] D) {
    long[] result = new long[N];
    result[0] = D[0];
    long currMax = D[0];
    for (int i = 1; i < N; i++) {
        currMax = Math.max(D[i], currMax + D[i]);
        result[i] = Math.max(result[i - 1], currMax);
    }
    return result;
}
function MaxSumSubarray(a, n, start out, len out)
    -- a - Array
    -- n - Length of the array
    -- start - On output starting position of largest subarray
    -- len - On output length of largest subarray
    -- Returns sum of the largest subarray
begin

    start = 0
    len = 1
    int sum = a[0]

    curStart = 0
    curLen = 1
    curSum = a[0]

    for i = 2 to n
        begin
            if a[i] >= curSum + a[i] then
                begin
                    curStart = i
                    curLen = 1
                    curSum = a[i]
                end
            else
                begin
                    curLen = curLen + 1
                    curSum = curSum + a[i]
                end

            if (curSum > sum) OR
               (curSum = sum AND curLen < len) OR
               (curSum = sum AND curLen = len AND curStart < start) then
               begin
                    start = curStart
                    len = curLen
                    sum = curSum
                end

        end

    return sum

end
.....(I wrote it in Scala)
def findMaxSubArray(list: List[Int]): (Int, Int, Int) = {

 var (bestNow,bestSoFar) = (0, 0)
 var ( startIndexNow, startIndexSoFar, endIndex) = (-1, -1, -1)

 for (i <- 0 until list.length) {
   var value = bestNow + list(i)
   if (value > bestNow) {
     if (bestNow == 0)
       startIndexNow = i
     bestNow = value
   } else
     bestNow = 0

  if (bestNow > bestSoFar) {
    bestSoFar = bestNow
    startIndexSoFar = startIndexNow
    endIndex = i
    } 
  }

  return (bestSoFar, startIndexSoFar, endIndex)
 }     

 def main(args: Array[String]) {
  println(findMaxSubArray(List(3, -1, 5, 3, -6, -9, 6, 1)).toString)
  println(findMaxSubArray(List(3, -1, 5, 3, -6, -9, 6, 3)).toString)
  println(findMaxSubArray(List(20, -1, 5, 3, -6, -9, 6)).toString)
}

   Output.....
    (max =8, start=2, end=3)
    (max=9, start=6, end=7)
    (max=20, start=0, end= 0)