子集和排列

1 Subsets

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

2 Subsets II

    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        if (nums.length == 0) {
            return result;
        }
        Arrays.sort(nums);
        ArrayList<Integer> list = new ArrayList<>();
        subsetsHelper(nums, 0, list, result);
        return result;
    }
    void subsetsHelper(int[] nums, int pos, List<Integer> list, List<List<Integer>> result){
        result.add(new ArrayList<>(list));
        for (int i = pos; i < nums.length; i++) {
            if (i > pos && nums[i] == nums[i - 1]){
                continue;
            }
            list.add(nums[i]);
            subsetsHelper(nums, i + 1, list, result);
            list.remove(list.size() - 1);
        }
    }

3 Permutations

    public List<List<Integer>> permute(int[] nums) {
        // write your code here
        List<List<Integer>> res = new ArrayList<>();
        if (nums == null || nums.length == 0) {
            res.add(new ArrayList<Integer>());
            return res;
        }
        List<Integer> list = new ArrayList<>();
        helper(nums, list, res);
        return res;
    }

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

4 Permutations II

    public List<List<Integer>> permuteUnique(int[] nums) {
        // Write your code here
        List<List<Integer>> result = new ArrayList<>();
        if (nums == null || nums.length == 0) {
            result.add(new ArrayList<Integer>());
            return result;
        }
        Arrays.sort(nums);
        List<Integer> list = new ArrayList<>();
        boolean[] used = new boolean[nums.length];
        helper(nums, list, used, result);
        return result;
    }
    void helper(int[] nums, List<Integer> list, boolean[] used, List<List<Integer>> result) {
        if (list.size() == nums.length) {
            result.add(new ArrayList<>(list));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])) {
                continue;
            }
            used[i] = true;
            list.add(nums[i]);
            helper(nums, list, used, result);
            used[i] = false;
            list.remove(list.size() - 1);
        }
    }

5 Combination Sum    可以有重复

    public ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target)
    {
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
        if (candidates == null || candidates.length == 0)
        {
            return res;
        }
        Arrays.sort(candidates);
        helper(candidates, 0, target, new ArrayList<Integer>(), res);
        return res;
    }
    private void helper(int[] candidates, int start, int target, ArrayList<Integer> item,
            ArrayList<ArrayList<Integer>> res) {
        // TODO Auto-generated method stub
        if (target < 0)
        {
            return;
        }
        if (target == 0)
        {
            res.add(new ArrayList<>(item));
            return;
        }
        for (int i = start; i < candidates.length; i++)
        {
            if (i > 0 && candidates[i] == candidates[i - 1])
            {
                continue;
            }
            item.add(candidates[i]);
            helper(candidates, i, target - candidates[i], item, res);
            item.remove(item.size() - 1);
        }
    }

View Cod

6 Combination Sum     不可以有重复

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

}

private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){
    if(remain < 0) return;
    else if(remain == 0) list.add(new ArrayList<>(tempList));
    else{
        for(int i = start; i < nums.length; i++){
            if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates
            tempList.add(nums[i]);
            backtrack(list, tempList, nums, remain - nums[i], i + 1);
            tempList.remove(tempList.size() - 1);
        }
    }
} 

7 Palindrome Partitioning

public class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> res = new ArrayList<>();
        if (s.length() == 0) return res;
        dfs(s, 0, new ArrayList<String>(), res);
        return res;
    }
    public void dfs(String s, int index, ArrayList<String> item, List<List<String>> res){
        if (s.length() == index) {
            res.add(new ArrayList<>(item));
            return;
        }
        for (int i = index; i < s.length(); i++){
            if (isP(s, index, i)){
                item.add(s.substring(index, i + 1));
                dfs(s, i + 1, item, res);
                item.remove(item.size() - 1);
            }
        }
    }
    public boolean isP(String s, int l, int r){
        while (l < r) {
            if (s.charAt(l) != s.charAt(r)){
                return false;
            }
            l++;r--;
        }
        return true;
    }
}

时间: 2024-10-23 15:21:43

子集和排列的相关文章

SCU 4424(求子集排列数)

A - A Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice SCU 4424 Description Time Limit: 1000ms Description Given N distinct elements, how many permutations we can get from all the possible subset of the eleme

HDU 2062 Subset sequence

我是把它当做一道数学题来做的. 这篇题解写的有点啰嗦,但是是我最原始的思维过程. 对于一个集合An= { 1, 2, …, n },在n比较小的情况下,在纸上按字典顺序把所有子集排列一下. 以n=3,m=10举例: 1 1 2 1 2 3 1 3 1 3 2 2 2 1 2 1 3 2 3 2 3 1 3 3 1 3 1 2 3 2 3 2 1 n=3的情况 容易看出前5个打头的是1,紧接着5个子集打头的是2,最后5个开头的是3. 拿前五个来说,除了第一个,后面四个不看开头的1,后面的排列形式和

UVa1601 Morning after holloween 解题分析

只有思路还没有实践 这个题一眼看上去就是典型的状态空间搜索问题,a,b,c的每一个不同摆放位置都是一个状态,每一个状态都可以看成无权有向无环状图上的一个节点.又是找移动步数最少的走法,很自然就会想到用BFS. 细想上去,这个题稍微麻烦的地方是,如何从一个状态扩展到下一个状态.每个状态有2个或者3个字母需要考虑. 本以为只要考虑先尝试移动a,然后b,最后考虑移动c, 每个字母在四个方向上各尝试移动一步就可以了,那么对于一个状态,需要尝试的下一个状态数目只是4*4*4.其实不对,第一步移动a和第一步

[Leetcode 46]全排列 Permutations 递归

[题目] Given a collection of distinct integers, return all possible permutations. 数组的组合情况. Input: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] [思路] 求子集,排列组合的数组题有固定模板. [代码] class Solution { public List<List<Integer>> p

2020.3.28-ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016

A.Majestic 10 签到题. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> #include<cassert> #include<cctype> #include<cmath> #include<cstdlib> #include<ctime>

子集树和排列树

假设现在有一列数a[0],a[1], ...a[n-1] ①如果一个问题的解的长度不是固定的,并且解和元素顺序无关,即可以从中选择0个或多个,那么解空间的个数将是指数级别的,为2^n,可以用下面的子集树来表示所有的解 子集树的算法框架为: void backtrack(int t) {//表示访问到第t层,t从0开始 if (t == n) output(x); else for (int i = 0; i <= l; i++) { //表示选或不选a[t] x[t] = i; if (cons

回溯之子集树和排列树(子集和问题)

一.子集树          子集树:当所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间称为子集树.例如,那个物品的0-1背包问题所相应的解空间树就是一颗子集树.这类子集问题通常有2^n个叶节点,其节点总个数为2^(n+1)-1.遍历子集树的任何算法均需要O(2^n)的计算时间. \ void backtrack (int t) { if (t>n) output(x); else for (int i=0;i<=1;i++) { x[t]=i; if (legal(t)

生成1~~n的排列 &amp;&amp; 子集

int print_permutation(int n,int *A,int cur) { if(cur==n) { for(int i=0;i<n;i++) printf("%d",A[i]); printf("\n"); } else { for(int i=1;i<=n;i++) //填各种数 { int ok = 1; for(int j= 0; j<cur; j++) //判断是否重复出现 if( A[j]==i ) ok=0; // 1

两种典型的解空间树:子集树和排列树

(1)定义 子集树:所给问题是从N个元素的集合中找出满足某种性质的子集时,相应的解空间树,称为子集树.子集树通常有2^n个叶节点,遍历子集树的任何算法都需要O(2^n)的计算时间. 例如:0-1背包问题的解空间树为一棵子集树. 排列树:当所给的问题是确定N个元素满足某种性质的排列时,相应的解空间称为排列树,排列树通常有N!个叶节点,因此,遍历排列树需要N!的计算时间. 例如:旅行售货员问题的解空间树为一棵排列树. (2)回溯法遍历实现 1.搜索子集树 1 void backtrack (int