1. 程式人生 > >python求解最大子序列乘積問題,子序列可連續也可不連續

python求解最大子序列乘積問題,子序列可連續也可不連續

    題目意思很簡單,與之前博文中的最大子序列和問題其實是如出一轍的,只是這裡需要考慮的問題會多一點,因為加法的話不會出現負負得正的情況,在這裡要求最大子序列乘積就需要維持兩個動態遍歷,一個儲存上一次乘積留下的最大值,一個儲存上一次乘積留下的最小值,這裡如果接下來的數字為正的話最大值的結果發揮作用,如果接下來的值為負數的話最小值發揮作用,有了這個考慮接下來就可以按照這個思路來做了。

1.對於子序列可以不連續的最大子序列乘積

    這個很簡單,就不用動態規劃什麼的了,我採用的方法是遍歷陣列,將正數且大於1的放在正數列表中,將負數放入負數列表中,之後直接累積求正數列表,對於負數列表的判斷需要加一層判斷,長度是否為偶數,是偶數則處理方法同正數列表,不是偶數的話需要先排序去除最後位置的數字之後處理方法同正數 列表,下面是具體實現:

def test_func(num_list):
    '''
    求陣列中最大子序列的乘積,子序列可以不連續
    '''
    positive_num_list=[one for one in num_list if one>1]
    negative_num_list=[one for one in num_list if one<0]
    negative_num_list.sort()
    # print 'positive_num_list', positive_num_list
    # print 'negative_num_list', negative_num_list
    length=len(negative_num_list)
    res1=res2=1
    if positive_num_list:
        res1=reduce(lambda x,y:x*y,positive_num_list)
    if negative_num_list:
        if length%2!=0:
            negative_num_list=negative_num_list[:-1]
        res2=reduce(lambda x,y:x*y,negative_num_list)
    print '最大子序列乘積為(子序列可不連續)', res1*res2

2.對於子序列必須連續

    這個只要別忘記負負得正情況的存在就不會錯了,因為負負得正的存在,最大值可能變成最小值,最小值也能變成最大值,下面是具體的實現:

def test_func2(num_list):
    '''
    求陣列中最大子序列的乘積,子序列必須連續
    '''
    length=len(num_list)
    max_positive=num_list[0]
    min_positive=num_list[0]
    tmp=num_list[0]
    for i in range(1,length):
        one=max_positive*num_list[i]
        two=min_positive*num_list[i]
        max_positive=max(max(one,two), num_list[i])  #三者中最大值
        min_positive=min(min(one,two), num_list[i])  #三者中最小值
        tmp=max(tmp, max_positive)
    print '最大子序列乘積為(子序列連續)', tmp

完整的實現如下:
#!usr/bin/env python
#encoding:utf-8

'''
__Author__:沂水寒城
功能:最大子序列乘積問題
'''

from functools import reduce


def test_func(num_list):
    '''
    求陣列中最大子序列的乘積,子序列可以不連續
    '''
    positive_num_list=[one for one in num_list if one>1]
    negative_num_list=[one for one in num_list if one<0]
    negative_num_list.sort()
    # print 'positive_num_list', positive_num_list
    # print 'negative_num_list', negative_num_list
    length=len(negative_num_list)
    res1=res2=1
    if positive_num_list:
        res1=reduce(lambda x,y:x*y,positive_num_list)
    if negative_num_list:
        if length%2!=0:
            negative_num_list=negative_num_list[:-1]
        res2=reduce(lambda x,y:x*y,negative_num_list)
    print '最大子序列乘積為(子序列可不連續)', res1*res2



def test_func2(num_list):
    '''
    求陣列中最大子序列的乘積,子序列必須連續
    '''
    length=len(num_list)
    max_positive=num_list[0]
    min_positive=num_list[0]
    tmp=num_list[0]
    for i in range(1,length):
        one=max_positive*num_list[i]
        two=min_positive*num_list[i]
        max_positive=max(max(one,two), num_list[i])  #三者中最大值
        min_positive=min(min(one,two), num_list[i])  #三者中最小值
        tmp=max(tmp, max_positive)
    print '最大子序列乘積為(子序列連續)', tmp


if __name__ == '__main__':
    num_list=[[-4 , 3 ,56 , -15 , 34 , 0 , -14 , 4],[-9,-11,-0.5,-4],[7,3,1,4,5]]
    for one_list in num_list:
        print 'num_list', one_list
        test_func(one_list)
        test_func2(one_list)
        print '----------------------------------------------------'


結果如下:
num_list [-4, 3, 56, -15, 34, 0, -14, 4]
最大子序列乘積為(子序列可不連續) 4798080
最大子序列乘積為(子序列連續) 342720
----------------------------------------------------
num_list [-9, -11, -0.5, -4]
最大子序列乘積為(子序列可不連續) 198.0
最大子序列乘積為(子序列連續) 198.0
----------------------------------------------------
num_list [7, 3, 1, 4, 5]
最大子序列乘積為(子序列可不連續) 420
最大子序列乘積為(子序列連續) 420
----------------------------------------------------
[Finished in 0.3s]