LeetCode-241. 爲運算表達式設計優先級
給定一個含有數字和運算符的字符串,爲表達式添加括號,改變其運算優先級以求出不同的結果。你需要給出所有可能的組合的結果。有效的運算符號包含 +, - 以及 * 。
示例 1:
輸入: "2-1-1"
輸出: [0, 2]
解釋:
((2-1)-1) = 0
(2-(1-1)) = 2
示例 2:
輸入: "2*3-4*5"
輸出: [-34, -14, -10, -10, 10]
解釋:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
思路
- 給一段帶有運算符的字符串加上括號之後就會輸出不同的結果。單純地給一個數字加括號,如給2加成(2),2還是2。
- 我們從前向後遍歷字符串,遇到運算符後就開始進行分而治之。分而治之的思想關鍵是,對於每個分治的部分,採取相同的計算邏輯。先計算這個運算符左邊的子串加括號之後的各種結果,然後計算它右邊子串加括號後的各種結果。
- 這種思想實際上是對這個運算符的左邊和右邊先加了一個大括號,然後對每個大括號中的子串施行一致的計算邏輯。直到遍歷完這個子串。如果在遍歷過程中,沒有發現運算符,則這個大括號中只能存在一種計算結果,也就是單純地給一個數字加括號的情況。
- 相關API
- substring(0,i) 是獲得字符數組下標0到i-1處的子串。
- substring(i+1)是獲得字符數組下標i+1到末尾的子串。具體重載方法請參照JDK。
class Solution {
public List<Integer> diffWaysToCompute(String input) {
List<Integer> res=new ArrayList<Integer>();
if(input==null) return res;
for(int i=0;i<input.length();i++)
{
char c=input.charAt(i);
if(c=='+' || c=='*' || c=='-')
{
//處理左邊,收集左邊的各種情況,此處的分治相當於給左邊加了一個大括號
List<Integer> left=diffWaysToCompute(input.substring(0,i));
//處理右邊,收集右邊的各種情況,此處的分治相當於給右邊加了一個大括號
List<Integer> right=diffWaysToCompute(input.substring(i+1));
//遍歷左邊和右邊收集的加括號之後的各種計算結果
for(int l:left)
{
for(int r:right)
{
//然分治的結果是左右兩邊各加大括號的結果,所以將目光聚集在當前的運算符上即可
switch(c){
case '+':
res.add(l+r);
break;
case '-':
res.add(l-r);
break;
case '*':
res.add(l*r);
break;
}
}
}
}
}
//如果某次遍歷完字符串沒有發現運算符,那麼直接將字符串轉爲int返回
//可以理解爲給單獨的一個數字加了一個無所謂有沒有的括號
if(res.size()==0)
{
res.add(Integer.valueOf(input));
}
return res;
}
}