python求解最大子序列乘积问题,子序列可连续也可不连续

来源:互联网 发布:mac chrome 常用插件 编辑:程序博客网 时间:2024/06/05 16:26

    题目意思很简单,与之前博文中的最大子序列和问题其实是如出一辙的,只是这里需要考虑的问题会多一点,因为加法的话不会出现负负得正的情况,在这里要求最大子序列乘积就需要维持两个动态遍历,一个保存上一次乘积留下的最大值,一个保存上一次乘积留下的最小值,这里如果接下来的数字为正的话最大值的结果发挥作用,如果接下来的值为负数的话最小值发挥作用,有了这个考虑接下来就可以按照这个思路来做了。

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 reducedef 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*res2def 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 '最大子序列乘积为(子序列连续)', tmpif __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]