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:
- The length of the input array is [1, 10].
- Elements in the given array will be in range [2, 1000].
- 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的+运算来连接字符串。