Leetcode算法学习日志-553 Optimal Division

Leetcode 553 Optimal Division

题目原文

Given a list of positive integers, the adjacent integers will perform the float division. For example, [2,3,4] -> 2 / 3 / 4.

However, you can add any number of parenthesis at any position to change the priority of operations. You should find out how to add parenthesis to get the maximum result, and return the corresponding expression in string format. Your expression should NOT contain redundant parenthesis.

Example:

Input: [1000,100,10,2]
Output: "1000/(100/10/2)"
Explanation:
1000/(100/10/2) = 1000/((100/10)/2) = 200
However, the bold parenthesis in "1000/((100/10)/2)" are redundant, 
since they don't influence the operation priority. So you should return "1000/(100/10/2)". 

Other cases:
1000/(100/10)/2 = 50
1000/(100/(10/2)) = 50
1000/100/10/2 = 0.5
1000/100/(10/2) = 2

Note:

  1. The length of the input array is [1, 10].
  2. Elements in the given array will be in range [2, 1000].
  3. There is only one optimal division for each test case.

题意分析

求一串相除数据在加任意括号情况下的最大值,且所给数据只有一个最大值,将加括号之后的结果按字符串形式输出。对于不必要的括号不用输出。

解法分析

利用贪心思想和逆向思想,不管怎么加括号,最后一次必然也是两数相除,()/(),为了让结果最大,则需要让右边最小,由于全是除法,所以为了让右边最小,右边应该没有任何小括号,除法按从左到右的顺序进行,按除法的性质,除了右边第一个数,其他数都会变成左边数的乘数,使得结果变大,因此为了让尽可能多的数都能成为乘数,右方括号中的元素应该尽可能多,假设左边不只一个数,则可以肯定的是不管左边大括号中小括号如何分配,第一个数右边相邻的数一定是作为除数,并且左边大括号中元素还可能有作为除数的,因此可以让左边大括号中只有第一个数,右边大括号是所有其他元素,这样的话只有第二个数作为除数,其他所有元素都是乘数,对最终结果有积极贡献。例如:a/(b/c/d/e)=a*c*d*e/b。注意n=1、2时不需要加括号。C++代码如下:

class Solution {
public:
    string optimalDivision(vector<int>& nums) {
        int n=nums.size();
        string res;
        string temp;
        stringstream ss;
        int i;
        for(i=0;i<n;i++){
            if(n==1){
                ss<<nums[i];
                ss>>res;
            }
            else if(n==2){
                ss<<nums[i];
                ss>>temp;
                res+=temp;
                if(i==0)
                    res.push_back('/');  
                ss.clear();
                ss.str("");
            }
            else{
                ss<<nums[i];
                ss>>temp;
                res+=temp;
                res.push_back('/');
                if(i==n-1){
                    res.pop_back();
                    res.push_back(')');       
                }
                if(i==0)
                    res.push_back('(');
                ss.clear();
                ss.str("");
            }      
        }
        return res;    
    }
};
上述代码int和string的互相转化利用了sstrea头文件中的stringstrea类,值得注意的是,每次从stringstream对象读出后,都要用ss.clear()来清除状态,用ss.str("")来清空缓存空间,不然ss会因为进入eof状态而停止读入读出。另一种int和string转化的方法是to_string和stoi,C++代码如下:

class Solution {
public:
    string optimalDivision(vector<int>& nums) {
        string ans;
        if(!nums.size()) return ans;
        ans = to_string(nums[0]);
        if(nums.size()==1) return ans;
        if(nums.size()==2) return ans + "/" + to_string(nums[1]);
        ans += "/(" + to_string(nums[1]);
        for(int i = 2; i < nums.size();++i)
            ans += "/" + to_string(nums[i]);
        ans += ")";
        return ans;
    }
};
此代码巧妙运用了string的+运算来连接字符串。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值