组合排序回溯编程题集合(leetcode)

命运对每个人都是一样的,不一样的是各自的努力和付出不同,付出的越多,努力的越多,得到的回报也越多,在你累的时候请看一下身边比你成功却还比你更努力的人,这样,你就会更有动力。

导读:本篇文章讲解 组合排序回溯编程题集合(leetcode),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

回溯算法主要用于解决组合,切割,排序,子集,棋盘问题。

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:

输入:n = 4, k = 2

输出:

[

[2,4],

[3,4],

[2,3],

[1,2],

[1,3],

[1,4],

]

 public  List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> lists=new ArrayList<>();
        if(k<=0||n<k)
            return lists;
        ArrayList<Integer> list=new ArrayList<>();
        backtack(n,k,1,lists,list);
        return  lists;
 
    }
    public  void backtracking(int n,int k,int start,List<List<Integer>> lists,ArrayList<Integer> list){
        if(list.size()==k){
            lists.add(new ArrayList<>(list));
            return;
        }
        for(int i=start;i<=n;i++){
//            if(list.contains(i))
//                continue;
            list.add(i);
            backtack(n,k,i+1,lists,list);
            list.remove(list.size()-1);
        }
    }

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

输入: candidates = [10,1,2,7,6,1,5], target = 8,

输出:

[

[1,1,6],

[1,2,5],

[1,7],

[2,6]

]

public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> lists=new ArrayList<>();
        List<Integer> list=new ArrayList<>();
        Arrays.sort(candidates);
        backtracking(lists,list,target,candidates,0);
       return lists;
    }

    public void backtracking(List<List<Integer>> lists,List<Integer> list,int target,int[] candidates,int start){
        Integer collect = list.stream().collect(Collectors.summingInt(Integer::intValue));
        if(collect==target) {
            lists.add(new ArrayList<>(list));
            return;
        }
        if(collect>target)
            return;
        for(int i=start;i<candidates.length;i++){
            //大剪枝,如果target -candidates[i] < 0,那么后面的元素都会小于0,需要剪掉
            if(candidates[i]>target)
                continue;
            //同一层数值相同,需要剪掉,不然会造成重复
            if(i > start && candidates[i] == candidates[i-1]){
                continue;
            }
            list.add(candidates[i]);
            backtracking(lists,list,target,candidates,i+1);
            list.remove(list.size()-1);
        }
    }

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

只使用数字1到9

每个数字 最多使用一次

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

输入:k = 3, n = 7 输出: [[1,2,4]] 解释: 1 + 2 + 4 = 7 没有其他符合的组合了。

 public List<List<Integer>> combinationSum3(int k, int n) {
       List<List<Integer>> lists=new ArrayList<>();
       List<Integer> list=new ArrayList<>();
       int[] array=new int[]{1,2,3,4,5,6,7,8,9};
        int sum = Arrays.stream(array).limit(k).sum();
       if(sum>n)
           return lists;
       tracking(lists,list,k,n,0,array);
       return lists;
    }
    public void tracking(List<List<Integer>> lists,List<Integer> list,int k,int n,int start,int[] array){
        int sum = list.stream().mapToInt(Integer::intValue).sum();
        if(sum==n&&list.size()==k){
            lists.add(new ArrayList<>(list));
            return;
        }
        if(sum>n||list.size()>k)
            return;
        for(int i=start;i<array.length;i++){
            if(array[i]>n)
                continue;
            list.add(array[i]);
            tracking(lists,list,k,n,i+1,array);
            list.remove(list.size()-1);
        }
    }

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

public  List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> lists=new ArrayList<>();
            if(nums.length==0)
            return lists;
        ArrayList<Integer> list=new ArrayList<>();
        backtracking(lists,list,nums);
        return  lists;

    }
    public  void backtracking(List<List<Integer>> lists,ArrayList<Integer> list,int[] nums){
        if(list.size()==nums.length){
            lists.add(new ArrayList<>(list));
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(list.contains(nums[i]))
                continue;
            list.add(nums[i]);
            backtracking(lists,list,nums);
            list.remove(list.size()-1);
        }
    }

已知一个长度为 N 的数组:A1, A2, A3, …AN 恰好是 1 ∼ N 的一个排列。现在要求你将 A 数组切分成若干个 (最少一个,最多 N 个) 连续的子数组,并且每个子数组中包含的整数恰好可以组成一段连续的自然数。

例如对于 A = {1, 3, 2, 4}, 一共有 5 种切分方法:

{1}{3}{2}{4}:每个单独的数显然是 (长度为 1 的)
一段连续的自然数

{1}{3, 2}{4}:{3, 2} 包含 2 到 3,是
一段连续的自然数,另外 {1} 和 {4} 显然也是。

{1}{3, 2, 4}:{3, 2, 4} 包含 2 到 4,是
一段连续的自然数,另外 {1} 显然也是。

{1, 3, 2}{4}:{1, 3, 2} 包含 1 到 3,是
一段连续的自然数,另外 {4} 显然也是。

{1, 3, 2, 4}:只有一个子数组,包含 1 到 4,是
一段连续的自然数

输入格式

第一行包含一个整数 N。第二行包含 N 个整数,代表 A 数组。

输出格式

输出一个整数表示答案。由于答案可能很大,所以输出其对 1000000007 取模后的值。

样例输入

复制

4 1 3 2 4

样例输出

复制

5

public class m {
static int result=0;
    public static void main(String[] args) {
        Scanner sc=newScanner(System.in);
        int n=sc.nextInt();
        int[] arr=newint[n];
        for(int i=0;i<arr.length;i++)
            arr[i]=sc.nextInt();
        backtreeing(arr, 0);
        System.out.println(result);    
        
    }
    public static void backtreeing(int arr[],int start) {
        if(start==arr.length) {
            result++;
            return;
        }
        for(int i=start;i<arr.length;i++) {
            if(check(arr, start, i)) {
                backtreeing(arr, i+1);
            }
        }
    }
      private static boolean check(int[] a, int l, int r) {
            intmax= Integer.MIN_VALUE, min = Integer.MAX_VALUE;
            for (int i= l; i <= r; i++) {
                if (a[i] > max) max = a[i];
                if (a[i] < min) min = a[i];
            }
            return max - min == r - l;
        }

}
组合排序回溯编程题集合(leetcode)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/143061.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!