553. 最优除法

给定一组正整数,相邻的整数之间将会进行浮点除法操作。例如, [2,3,4] -> 2 / 3 / 4 。

但是,你可以在任意位置添加任意数目的括号,来改变算数的优先级。你需要找出怎么添加括号,才能得到最大的结果,并且返回相应的字符串格式的表达式。你的表达式不应该含有冗余的括号。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/optimal-division
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

递归

class Solution {

    private Info solve(int[] nums, int left, int right) {
        if (left == right) {
            return new Info(nums[left], String.valueOf(nums[left]), nums[right], String.valueOf(nums[right]));
        }
        if (left + 1 == right) {
            return new Info((double) nums[left] / nums[right], nums[left] + "/" + nums[right], (double) nums[left] / nums[right], nums[left] + "/" + nums[right]);
        }

        Info ans = new Info(Double.MAX_VALUE, null, Double.MIN_VALUE, null);

        for (int i = left; i < right; ++i) {
            Info info1 = solve(nums, left, i);
            Info info2 = solve(nums, i + 1, right);
            if (info1.minValue / info2.maxValue < ans.minValue) {
                ans.minValue = info1.minValue / info2.maxValue;
                ans.minOp = info1.minOp + "/" + (right - i == 1 ? info2.maxOp : ("(" + info2.maxOp + ")"));
            }

            if (info1.maxValue / info2.minValue > ans.maxValue) {
                ans.maxValue = info1.maxValue / info2.minValue;
                ans.maxOp = info1.maxOp + "/" + (right - i == 1 ? info2.minOp : ("(" + info2.minOp + ")"));
            }
        }
        return ans;
    }

    public String optimalDivision(int[] nums) {
        if (nums == null || nums.length == 0) {
            return "";
        }
        return solve(nums, 0, nums.length - 1).maxOp;
    }
}

class Info {
    double minValue;
    String minOp;
    double maxValue;
    String maxOp;

    public Info(double minValue, String minOp, double maxValue, String maxOp) {
        this.minValue = minValue;
        this.minOp = minOp;
        this.maxValue = maxValue;
        this.maxOp = maxOp;
    }
}

记忆化搜素

class Solution {

    private Info[][] dp;

    private Info solve(int[] nums, int left, int right) {
        if (dp[left][right] == null) {
            if (left == right) {
                dp[left][right] = new Info(nums[left], String.valueOf(nums[left]), nums[right], String.valueOf(nums[right]));
            } else if (left + 1 == right) {
                dp[left][right] = new Info((double) nums[left] / nums[right], nums[left] + "/" + nums[right], (double) nums[left] / nums[right], nums[left] + "/" + nums[right]);
            } else {
                Info ans = new Info(Double.MAX_VALUE, null, Double.MIN_VALUE, null);
                for (int i = left; i < right; ++i) {
                    Info info1 = solve(nums, left, i);
                    Info info2 = solve(nums, i + 1, right);
                    if (info1.minValue / info2.maxValue < ans.minValue) {
                        ans.minValue = info1.minValue / info2.maxValue;
                        ans.minOp = info1.minOp + "/" + (right - i == 1 ? info2.maxOp : ("(" + info2.maxOp + ")"));
                    }
                    if (info1.maxValue / info2.minValue > ans.maxValue) {
                        ans.maxValue = info1.maxValue / info2.minValue;
                        ans.maxOp = info1.maxOp + "/" + (right - i == 1 ? info2.minOp : ("(" + info2.minOp + ")"));
                    }
                }
                dp[left][right] = ans;
            }
        }
        return dp[left][right];
    }

    public String optimalDivision(int[] nums) {
        if (nums == null || nums.length == 0) {
            return "";
        }
        this.dp = new Info[nums.length][nums.length];
        return solve(nums, 0, nums.length - 1).maxOp;
    }
}

class Info {
    double minValue;
    String minOp;
    double maxValue;
    String maxOp;

    public Info(double minValue, String minOp, double maxValue, String maxOp) {
        this.minValue = minValue;
        this.minOp = minOp;
        this.maxValue = maxValue;
        this.maxOp = maxOp;
    }
}

动态规划

数学

class Solution {
    public String optimalDivision(int[] nums) {
        int n = nums.length;
        if (n == 1) {
            return String.valueOf(nums[0]);
        }
        if (n == 2) {
            return nums[0] + "/" + nums[1];
        }
        StringBuffer res = new StringBuffer();
        res.append(nums[0]).append("/(").append(nums[1]);
        for (int i = 2; i < n; i++) {
            res.append("/");
            res.append(nums[i]);
        }
        res.append(")");
        return res.toString();
    }
}
上一篇:leecode 题目92 反转链表 II(python)


下一篇:F10-MYSQL的yum&源码