1. 题目描述
给定一个数组,这里假设数组中的数字全不相同,给定左右边界为L和R,每两个数字为一组,求数组中有多少这样的组合符合 L<= num1 + num2 <= R.
1 <= num[i] <= 10000.
L, R均为大于1的正数,且L < R.
示例1:
输入:
3 4 7
5 1 2
输出:2
解释:第一行中3表示数组的大小,4和7分别是L和R,第二行为数组中的数字。
示例2:
输入:
5 5 8
5 1 2 3 4
2. 题解
此题为“从n个数中选2个”的组合题目。
//main方法
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int L = scanner.nextInt();
int R = scanner.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = scanner.nextInt();
}
List<Integer> list = new ArrayList<>();
zuhe(arr, L, R, list, 0);
System.out.println(count);
}
//声明全局变量记录结果
public static int count = 0;
public static void zuhe(int[] arr, int L, int R, List<Integer> list, int currIndex){
//剪枝,这里 arr.length-currIndex 表示遍历到当前位置还有几个数字可以用
if(list.size() + arr.length-currIndex < 2){
return;
}
//记录合法答案
if(list.size() == 2){
int sum = list.get(0) + list.get(1);
if(sum >= L && sum <= R){
count++;
}
//list.clear(); 注意这里不能之间清除,后面有撤销选择的地方
return;
}
//做出选择
list.add(arr[currIndex]);
//进入下一轮递归
zuhe(arr, L, R, list,currIndex+1);
//撤销选择
list.remove(list.get(list.size()-1));
//进入下一轮递归
zuhe(arr, L, R, list,currIndex+1);
}
3. 组合问题的解题框架
n个数选k个数的组合问题。
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
List<Integer> list = new ArrayList<>();
backtrack(list, n, k, 1);
return res;
}
public void backtrack(List<Integer> list, int n, int k, int curr){
//剪枝:将不能构成组合的情况剪掉
if(list.size() + n-curr+1 < k){
return;
}
if(list.size() == k){
//对list进行浅拷贝,如果直接add(list),当list变化时,res会随之变化;
res.add(new ArrayList(list));
return;
}
//选择当前数字
list.add(curr);
//递归到下一状态
backtrack(list, n, k, curr+1);
//不选当前数字
list.remove(list.get(list.size()-1));
//递归到下一状态
backtrack(list, n, k, curr+1);
}
}