Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 2708. Maximum Strength of a Group

Woodyiiiiiii opened this issue · comments

2708. Maximum Strength of a Group

2708. Maximum Strength of a Group
O(2^N) 状压DP

这道题,我一看到数据范围,就觉得不需要记忆化搜索,直接暴力递归即可。不过,这道题想记忆化搜索都不需要。其实,这样子时间复杂度是2^n,因为类似一个二叉树结构,选或者不选。

接着,看到是乘法, 且存在负数,top-down返回的最大值与当前值不一定能组成最大值,所以top-down也要返回最小值,以防负数的出现。同时也要跟当前值做比较进行取舍。

class Solution {
    int n;
    int[] nums;

    public long maxStrength(int[] nums) {
        n = nums.length;
        this.nums = nums;
        long[] ans = dfs(0);
        return ans[1];
    }

    private long[] dfs(int i) {
        if (i >= n) {
            return new long[]{1, 1};
        }
        long[] next = dfs(i + 1);
        long max = Math.max(Math.max(i == n - 1 ? -10 : next[1], i == n - 1 ? -10 : next[0]), Math.max(nums[i] * next[0], nums[i] * next[1]));
        max = Math.max(max, nums[i]);
        long min = Math.min(Math.min(i == n - 1 ? 10 : next[1], i == n - 1 ? 10 : next[0]), Math.min(nums[i] * next[0], nums[i] * next[1]));
        min = Math.min(min, nums[i]);
        return new long[]{min, max};
    }
}

那么其实还有O(nlgn)甚至O(n)的解法——贪心。正值肯定都取,负数要取最小的偶数个,0的话看情况取。注意corn case。

class Solution {
    public long maxStrength(int[] nums) {
        if (Arrays.stream(nums).allMatch(num -> num == 0)) {
            return 0;
        }
        long ans = 1;
        int negativeCount = 0, positiveCount = 0;
        for (int num : nums) {
            if (num > 0) {
                ans *= num;
                positiveCount ++;
            } else if (num < 0) {
                negativeCount ++;
            }
        }
        Arrays.sort(nums);
        if (negativeCount % 2 == 0) {
            for (int num : nums) {
                if (num < 0) {
                    ans *= num;
                }
            }
        } else {
            int cnt = negativeCount - 1;
            for (int num : nums) {
                if (cnt == 0) {
                    break;
                }
                if (num < 0) {
                    ans *= num;
                    cnt--;
                }
            }
        }
        
        if (positiveCount == 0 && negativeCount == 1) {
            ans = nums.length == 1 ? nums[0] : 0;
        }

        return ans;
    }
}