LeetCode-553 最优除法

简介: LeetCode-553 最优除法

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/optimal-division

题目描述

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

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

示例:

输入: [1000,100,10,2]

输出: "1000/(100/10/2)"

解释:

1000/(100/10/2) = 1000/((100/10)/2) = 200

但是,以下加粗的括号 "1000/((100/10)/2)" 是冗余的,

因为他们并不影响操作的优先级,所以你需要返回 "1000/(100/10/2)"。

其他用例:

1000/(100/10)/2 = 50

1000/(100/(10/2)) = 50

1000/100/10/2 = 0.5

1000/100/(10/2) = 2

说明:

输入数组的长度在 [1, 10] 之间。

数组中每个元素的大小都在 [2, 1000] 之间。

每个测试用例只有一个最优除法解。

解题思路

首先,需要求数值最大,那么需要分子最大分母最小,由于数组中所有数都大于1,并且所有运算均为除法,所以当第一个数为分子的时候,分子最大,接下来需要分母最小,在分母的位置,同样,由于除数均大于0,所以一直连除分母最小,那么将第一个数之后的数全部使用括号括起来就好了。

此题同样也可用动态规划来做,dp[i][j] 中,表示 i 到 j 中所有的信息,包括最大值,最小值,和括号情况,通过一个结构体来记录。状态转移方程为 dp[i][j].max = max(dp[i][k].max / dp[k + 1][j].min) 和 dp[i][j].min= max(dp[i][k].min/ dp[k + 1][j].max ),其中k是i和j之间的数。

代码展示

数学方法:

class Solution {
public:
    string optimalDivision(vector<int>& nums) {
        int n = nums.size();
        if(n == 1) return to_string(nums[0]);
        else if(n == 2) return to_string(nums[0]) + "/" + to_string(nums[1]);
        else
        {
            string strRet;
            strRet += to_string(nums[0]) + "/(" + to_string(nums[1]);
            for(int i = 2; i < n; i++)
            {
                strRet += "/" + to_string(nums[i]);
            }
            strRet += ")";
            return strRet;
        }
    }
};

动态规划:

 

class Solution {
public:
    struct node
    {
        string mstrMax, mstrMin;
        double mdMax = DBL_MIN, mdMin = DBL_MAX;
    };
    string optimalDivision(vector<int>& nums) {
        int n = nums.size();
        vector<vector<node>> dp(n, vector<node>(n));
        for(int i = 0; i < n; i++)
        {
            dp[i][i].mdMax = dp[i][i].mdMin = nums[i];
            dp[i][i].mstrMax = dp[i][i].mstrMin = to_string(nums[i]);
        }
        for(int i = 1; i < n; i++)
        {
            for(int j = 0; j + i < n; j++)
            {
                for(int k = j; k < i + j; k++)
                {
                    if(dp[j][i + j].mdMax < dp[j][k].mdMax / dp[k + 1][i + j].mdMin)
                    {
                        dp[j][i + j].mdMax = dp[j][k].mdMax / dp[k + 1][i + j].mdMin;
                        if(k + 1 == i + j)
                        {
                           dp[j][i + j].mstrMax =  dp[j][k].mstrMax + "/" + dp[k + 1][i + j].mstrMin;
                        }
                        else
                        {
                            dp[j][i + j].mstrMax =  dp[j][k].mstrMax + "/(" + dp[k + 1][i + j].mstrMin + ")";
                        }
                    }
                    if(dp[j][i + j].mdMin > dp[j][k].mdMin / dp[k + 1][i + j].mdMax)
                    {
                        dp[j][i + j].mdMin = dp[j][k].mdMin / dp[k + 1][i + j].mdMax;
                        if(k + 1 == i + j)
                        {
                           dp[j][i + j].mstrMin =  dp[j][k].mstrMin + "/" + dp[k + 1][i + j].mstrMax;
                        }
                        else
                        {
                            dp[j][i + j].mstrMin =  dp[j][k].mstrMin + "/(" + dp[k + 1][i + j].mstrMax + ")";
                        }
                    }
                }
            }
        }
        return dp[0][n - 1].mstrMax;
    }
};

运行结果

 

相关文章
|
3月前
|
算法 Go
golang力扣leetcode 399.除法求值
golang力扣leetcode 399.除法求值
41 0
|
2月前
|
存储 算法 数据挖掘
深入解析力扣166题:分数到小数(模拟长除法与字符串操作详解及模拟面试问答)
深入解析力扣166题:分数到小数(模拟长除法与字符串操作详解及模拟面试问答)
|
3月前
|
存储 人工智能 BI
leetcode 399 除法求值
leetcode 399 除法求值
24 1
|
3月前
|
人工智能 BI
leetcode-399:除法求值
leetcode-399:除法求值
49 0
|
3月前
leetcode-553:最优除法
leetcode-553:最优除法
28 0
力扣题 两数相除:画图解析 采用递归计算除法(不使用乘法、除法和 mod 运算符)
这是力扣上的一道题目,难度为中等,两数相除:给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
力扣题 两数相除:画图解析 采用递归计算除法(不使用乘法、除法和 mod 运算符)
|
算法
[leetcode] 最优除法 小思维
如果是仅有一个数的时候直接返回那个数即可 如果有两个数,答案就是“a/b” 如果是三个数以上{ 为了让结果最大,那么说要让被除数更小。在整数的情况下,除法只会让数越除越小,所以说把除了第一个数之外的所有数放在括号里,比如: a/(b/c/d/…/f) }
75 0
[leetcode] 最优除法 小思维
|
13天前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
27 6