Algorithm to find the maximum subsequence of an array of positive numbers . Catch : No adjacent elements allowed

前端 未结 13 1179
甜味超标
甜味超标 2020-12-24 04:42

For example, given

A = [1,51,3,1,100,199,3], maxSum = 51 + 1 + 199 = 251.

clearly max(oddIndexSum,evenIndexSum) does not

13条回答
  •  被撕碎了的回忆
    2020-12-24 04:56

    You can build the maximal subsequence step by step if you keep two states:

    def maxsubseq(seq):
      # maximal sequence including the previous item
      incl = []
      # maximal sequence not including the previous item
      excl = []
    
      for i in seq:
        # current max excluding i
        if sum(incl) > sum(excl):
          excl_new = incl
        else:
          excl_new = excl
    
        # current max including i
        incl = excl + [i]
    
        excl = excl_new
    
      if sum(incl) > sum(excl):
        return incl
      else:
        return excl
    
    
    print maxsubseq([1,4,6,3,5,7,32,2,34,34,5])
    

    If you also want to have negative elements in your lists, you have to add a few ifs.

    Same -- in lesser lines

    def maxsubseq2(iterable):
        incl = [] # maximal sequence including the previous item
        excl = [] # maximal sequence not including the previous item
    
        for x in iterable:
            # current max excluding x
            excl_new = incl if sum(incl) > sum(excl) else excl
            # current max including x
            incl = excl + [x]
            excl = excl_new
    
        return incl if sum(incl) > sum(excl) else excl
    

    Same -- eliminating sum()

    def maxsubseq3(iterable):
        incl = [] # maximal sequence including the previous item
        excl = [] # maximal sequence not including the previous item
        incl_sum, excl_sum = 0, 0
        for x in iterable:
            # current max excluding x
            if incl_sum > excl_sum:
                # swap incl, excl
                incl, excl = excl, incl
                incl_sum, excl_sum = excl_sum, incl_sum
            else:
                # copy excl to incl
                incl_sum = excl_sum #NOTE: assume `x` is immutable
                incl     = excl[:]  #NOTE: O(N) operation
            assert incl is not excl
            # current max including x
            incl.append(x)
            incl_sum += x
        return incl if incl_sum > excl_sum else excl
    

    Allright, let's optimize it...

    Version with total runtime O(n):

    def maxsubseq4(iterable):
        incl = [] # maximal sequence including the previous item
        excl = [] # maximal sequence not including the previous item
        prefix = [] # common prefix of both sequences
        incl_sum, excl_sum = 0, 0
        for x in iterable:
            if incl_sum >= excl_sum:
                # excl <-> incl
                excl, incl = incl, excl
                excl_sum, incl_sum = incl_sum, excl_sum
            else:
                # excl is the best start for both variants
                prefix.extend(excl) # O(n) in total over all iterations
                excl = []
                incl = []
                incl_sum = excl_sum
            incl.append(x)
            incl_sum += x
        best = incl if incl_sum > excl_sum else excl
        return prefix + best # O(n) once
    

提交回复
热议问题