组合问题汇总

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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值