典型的分治算法:归并排序

void sort(int[] nums, int lo, int hi) {
    int mid = (lo + hi) / 2;
    /****** 分 ******/
    // 对数组的两部分分别排序
    sort(nums, lo, mid);
    sort(nums, mid + 1, hi);
    /****** 治 ******/
    // 合并两个排好序的子数组
    merge(nums, lo, mid, hi);
}

241. Different Ways to Add Parentheses

1、不要思考整体,而是把目光聚焦局部,只看一个运算符

2、明确递归函数的定义是什么,相信并且利用好函数的定义

考察算式 1 + 2 * 3 - 4 * 5 首先考虑只有一层括号的可能性(不嵌套

(1) + (2 * 3 - 4 * 5)

(1 + 2) * (3 - 4 * 5)

(1 + 2 * 3) - (4 * 5)

(1 + 2 * 3 - 4) * (5)

其规律就是按照运算符 + - * 进行分割,分别给每个运算符左右加括号

对于 (1 + 2 * 3) - (4 * 5) 用减号作为分割将算式分解成两个算式 1 + 2 * 3 和 4 * 5

对于其中的 1 + 2 * 3 可以有两种加括号的方式,分别为

(1) + (2 * 3) = 7

(1 + 2) * (3) = 9

而对于 4 * 5 则只有一种加括号的方式

List<Integer> diffWaysToCompute(String input) {
	List<Integer> res = new LinkedList<>();
	for (int i = 0; i < input.glength(); i++) {
		char c = input.charAt(i);
		// 扫描算式 input 中的运算符
		if (c == '-' || c == '*' || c == '+') {
			// 分:以运算符为中心分割成两个字符串分别递归计算
			List<Integer> left = diffWaysToCompute(input.substring(0, i));
			List<Integer> right = diffWaysToCompute(input.substring(i+1));
			// 治:通过子问题结果合成原问题结果
			for (int a : left)
				for (int b : right)
					if (c == '+')
						res.add(a+b);
					else if (c == '-')
						res.add(a-b);
					else if (c == '*')
						res.add(a*b);
		}
	}
	// base case: 不存在运算符
	if (res.isEmpty()) {
		res.add(Integer.parseInt(input));
	}
	return res;
}

先「分」后「治」,先按照运算符将原问题拆解成多个子问题,然后通过子问题的结果来合成原问题的结果

递归函数必须有个 base case 用来结束递归,分治算法的 base case,代表着你「分」到什么时候可以开始「治」,此问题的结束条件为当算式中不存在运算符时