Middle-题目112:152. Maximum Product Subarray

题目原文:
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.
题目大意:
寻找最大乘积的连续子数组。
题目分析:
使用两个dp数组dpmax和dpmin,其中dpmax[i]和dpmin[i]分别表示以i为结尾的子数组的最大、最小乘积。那么初始化dpmax[0]和dpmin[0]均为nums[0],转移方程如下:
dpmax[i]=max(nums[i],dpmax[i1]nums[i],dpmin[i1]nums[i])
dpmin[i]=min(nums[i],dpmax[i1]nums[i],dpmin[i1]nums[i])
这是因为nums[i]可能是正数也可能是负数,如果是负数且前一项的最小积是负数,则会变成最大乘积,而如果最大乘积和最小乘积都是负数或0,且nums[i]是正数,则它本身是最大乘积。所以最大值和最小值可能有三种情况。
源码:(language:java)

public class Solution {
    public int maxProduct(int[] nums) {
        int length = nums.length;
        if(length==0)
            return 0;
        int[] dpmax = new int[length];
        int[] dpmin = new int[length];
        dpmax[0] = nums[0];
        dpmin[0] = nums[0];
        int max = dpmax[0];
        for(int i = 1;i<length;i++) {
            dpmax[i] = max(nums[i],dpmax[i-1]*nums[i],dpmin[i-1]*nums[i]);
            dpmin[i] = min(nums[i],dpmax[i-1]*nums[i],dpmin[i-1]*nums[i]);
            if(dpmax[i]>max)
                max=dpmax[i];
        }
        return max;
    }
    private int max(int a,int b,int c) {
        return a>b?(a>c?a:c):(b>c?b:c);
    }
    private int min(int a,int b,int c) {
        return a<b?(a<c?a:c):(b<c?b:c);
    }
}

成绩:
5ms,beats 10.47%,众数5ms,36.73%
cmershen 的碎碎念:
(1) 本题如果用一个dp数组,即dp[i][j]维护从i~j的最大乘积,也能实现但会超时。
(2) 对nums很长的情况下,可能会涉及到BigInteger高精度计算,题中没有超过int范围,故test case不够严密。
(3) 这是第一次遇到同时维护多个dp数组的题,也是拓宽了思路。

### Quick - Sort Algorithm Implementation The quick - sort algorithm is a divide - and - conquer sorting algorithm. Here is the Python implementation of the quick - sort algorithm: ```python import random import matplotlib.pyplot as plt from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas def partition(arr, low, high): pivot = arr[high] i = low - 1 for j in range(low, high): if arr[j] <= pivot: i = i + 1 arr[i], arr[j] = arr[j], arr[i] arr[i + 1], arr[high] = arr[high], arr[i + 1] return i + 1 def quick_sort(arr, low, high, steps): if low < high: pi = partition(arr, low, high) step_info = { "pivot": arr[pi], "left_subarray": arr[low:pi], "right_subarray": arr[pi + 1:high + 1], "current_array": arr.copy() } steps.append(step_info) quick_sort(arr, low, pi - 1, steps) quick_sort(arr, pi + 1, high, steps) # Generate a list of 9 random integers random_list = random.sample(range(1, 100), 9) sorting_steps = [] quick_sort(random_list, 0, len(random_list) - 1, sorting_steps) # Create a PDF file c = canvas.Canvas("q3.pdf", pagesize=letter) y = 750 c.drawString(100, y, "Quick Sort Process for Random List: " + str(random_list)) y -= 20 for step in sorting_steps: c.drawString(100, y, f"Pivot: {step['pivot']}") y -= 20 c.drawString(100, y, f"Left Subarray: {step['left_subarray']}") y -= 20 c.drawString(100, y, f"Right Subarray: {step['right_subarray']}") y -= 20 c.drawString(100, y, f"Current Array: {step['current_array']}") y -= 40 c.save() ``` ### Explanation 1. **Partition Function**: The `partition` function selects the last element as the pivot and rearranges the array so that all elements less than or equal to the pivot are on the left, and all elements greater than the pivot are on the right. It then returns the index of the pivot in its sorted position. 2. **Quick Sort Function**: The `quick_sort` function is a recursive function. It first partitions the array and then recursively sorts the left and right sub - arrays. It also records the pivot, sub - arrays, and the current state of the array at each step in the `sorting_steps` list. 3. **PDF Generation**: After the quick - sort process is completed, a PDF file named `q3.pdf` is created. The PDF includes the original random list and the details of each step in the quick - sort process, such as the pivot, left and right sub - arrays, and the current state of the array. ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值