152. 乘积最大子数组 AND 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

199 阅读2分钟

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

152. 乘积最大子数组

给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

示例 1:

输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6。 示例 2:

输入: [-2,0,-1] 输出: 0 解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

解题思路

最大子序和的变种问题,因为负负得正,负数相乘也可以得出最大值,因此我们还需要维护一个最小值.

代码

class Solution {
    public int maxProduct(int[] nums) {

        int max=nums[0],min=nums[0],res=nums[0];
        for (int i = 1; i < nums.length; i++) {
            int pm=max;
            max= Math.max(Math.max(nums[i],max*nums[i]),min*nums[i]);
            min= Math.min(Math.min(nums[i],min*nums[i]),pm*nums[i]);
            res=Math.max(max,res);
        }
        return res;
    }
}
  • 时间复杂度:程序一次循环遍历了 nums,故渐进时间复杂度为 O(n)。

  • 空间复杂度:优化后只使用常数个临时变量作为辅助空间,与 n 无关,故渐进空间复杂度为 O(1)。

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

示例:

输入:nums = [1,2,3,4] 输出:[1,3,2,4] 注:[3,1,2,4] 也是正确的答案之一。

提示:

0 <= nums.length <= 50000 1 <= nums[i] <= 10000

解题思路

来自于快排的思路,快排可以实现将小于中枢值和大于中枢值的分在数组的两边

我们也可以利用相同的思路,将奇数和偶数分别排布在两边

代码

class Solution {
    public int[] exchange(int[] nums) {

        int l=0,n=nums.length,r=n-1;
        while (l<r)
        {
            while (l<r&&nums[l]%2==1)
                l++;
            while (l<r&&nums[r]%2==0)
                r--;
            int t=nums[r];
            nums[r]=nums[l];
            nums[l]=t;
        }
        return nums;

    }
}