Find the contiguous subarray within an array containing at least one number which has the largest product. For example, given the array 2,3,2,4, the contiguous subarray 2,3 has the largest product  6. :type nums: Listint :rtype: int Another approach that would print max product and the subarray Examples: subarraywithmaxproduct2,3,6,1,1,9,5  maxproductsofar: 45, 1, 1, 9, 5 subarraywithmaxproduct2,3,6,0,7,5  maxproductsofar: 36, 2, 3, 6 subarraywithmaxproduct4,3,2,1  maxproductsofar: 24, 4, 3, 2, 1 subarraywithmaxproduct3,0,1  maxproductsofar: 1, 1 arr is list of positivenegative numbers ''' length  lenarr productsofar  maxproductend  1 maxstarti  0 sofarstarti  sofarendi  0 allnegativeflag  True for i in rangelength: maxproductend  arri if arri  0: allnegativeflag  False if maxproductend  0: maxproductend  arri maxstarti  i if productsofar  maxproductend: productsofar  maxproductend sofarendi  i sofarstarti  maxstarti if allnegativeflag: printfmaxproductsofar: reducelambda x, y: x  y, arr, arr else: printfmaxproductsofar: productsofar,arrsofarstarti:sofarendi  1
from functools import reduce


def max_product(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    lmin = lmax = gmax = nums[0]
    for num in nums:
        t_1 = num * lmax
        t_2 = num * lmin
        lmax = max(max(t_1, t_2), num)
        lmin = min(min(t_1, t_2), num)
        gmax = max(gmax, lmax)


"""
Another approach that would print max product and the subarray

Examples:
subarray_with_max_product([2,3,6,-1,-1,9,5])
    #=> max_product_so_far: 45, [-1, -1, 9, 5]
subarray_with_max_product([-2,-3,6,0,-7,-5])
    #=> max_product_so_far: 36, [-2, -3, 6]
subarray_with_max_product([-4,-3,-2,-1])
    #=> max_product_so_far: 24, [-4, -3, -2, -1]
subarray_with_max_product([-3,0,1])
    #=> max_product_so_far: 1, [1]
"""


def subarray_with_max_product(arr):
    ''' arr is list of positive/negative numbers '''
    length = len(arr)
    product_so_far = max_product_end = 1
    max_start_i = 0
    so_far_start_i = so_far_end_i = 0
    all_negative_flag = True

    for i in range(length):
        max_product_end *= arr[i]
        if arr[i] > 0:
            all_negative_flag = False

        if max_product_end <= 0:
            max_product_end = arr[i]
            max_start_i = i

        if product_so_far <= max_product_end:
            product_so_far = max_product_end
            so_far_end_i = i
            so_far_start_i = max_start_i

    if all_negative_flag:
        print(f"max_product_so_far: {reduce(lambda x, y: x * y, arr)}, {arr}")

    else:
        print(f"max_product_so_far: {product_so_far},{arr[so_far_start_i:so_far_end_i + 1]}")
