dfs 的全排列

 
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <string>
 5 #include <string>
 6 #include <cstring>
 7 #include <map>
 8 #include <utility>
 9 using namespace std;
10 const int  N = 1e2+20 ;
11 bool vis[N];
12 int a[N],n;
13 void dfs(int num,int n){
14     if(num==n){
15         for(int  i =0;i<n;i++){
16             printf("%d%c",a[i],i==n-1?'\n':' ');
17         }
18         return ;
19     }
20     for(int  i=1;i<=n;i++){
21         if(!vis[i]){
22             vis[i]=1;
23             a[num]=i;
24             dfs(num+1,n);
25             vis[i]=0;        
26         }
27     }
28 }
29 int  main()
30 {
31     while(~scanf("%d",&n)){
32         memset(vis,0,sizeof(vis));
33         dfs(0,n);
34     }
35     return  0;
36  } 

 

 

class Solution {
    boolean vis[]  =new boolean[7];
    int n;
    List<List<Integer>>list  = new ArrayList<List<Integer>>();
    void dfs(int num,int nums[],ArrayList<Integer>a){
          if(num==n){        
             list.add(new ArrayList<Integer>(a));
          }
          for(int i=0;i<n;i++){
              if(!vis[i]){
                  vis[i]  =true;
                  a.add(nums[i]);
                  dfs(num+1,nums,a);
                  a.remove(a.size()-1);
                  vis[i]  =false;
              }
          }
    }
    public List<List<Integer>> permute(int[] nums) {
        n = nums.length;
        dfs(0,nums,new ArrayList<Integer>());
        return list;
    }
}

 

 1 //用于生成全排列的函数
 2 int a[N],n;
 3 void init()
 4 {
 5     for(int   i=0;i<4;i++){
 6         a[i]=i+1;
 7     }
 8 }
 9 int main()
10 {
11     init();
12     int cnt=0;
13     do{
14         for(int   i=0;i<4;i++)
15         printf("%d%c",a[i],i==3?'\n':' '); 
16         cnt++;
17     }while(next_permutation(a,a+4));
18     printf("%d\n",cnt);
19     return 0;
20 }

 

 

 1 //从1到n取出m个数
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <string>
 6 #include <string>
 7 #include <cstring>
 8 #include <map>
 9 #include <utility>
10 using namespace std;
11 const int  N = 1e2+20 ;
12 bool vis[N];
13 int n,m,a[N];
14 void dfs(int  num,int n){
15     if(num==m+1){
16         for(int  i =1;i<=m;i++)
17         {
18             printf("%d%c",a[i],i==m?'\n':' ');
19         }
20         return ;
21     }
22     for(int i =a[num-1]+1;i<=n;i++){
23         if(!vis[i]){
24             vis[i]=1;
25             a[num]=i;
26             dfs(num+1,n);
27             vis[i]=0;
28         }
29     }
30 }
31 int  main()
32 {
33     while(~scanf("%d%d",&n,&m)){
34         memset(vis,0,sizeof(vis));
35         dfs(1,n);        
36     }
37     return  0;
38 }

 

import java.util.*;

public class Main {
    static int a[] = { 1, 3, 5, 7 };
    static boolean vis[] = new boolean[5];
    static List<List<Integer>> list = new ArrayList<List<Integer>>();

    public static void dfs(int num, int n, int m, int a[], ArrayList<Integer> tmp) {// num :tmp.size()
        System.out.println("num: " + num);
        System.out.println(tmp);
        if (tmp.size() == m) {
            list.add(new ArrayList<Integer>(tmp));
            return;
        }

        for (int i = num; i < n; i++) {// id

            tmp.add(a[i]);
            dfs(i + 1, n, m, a, tmp);
            tmp.remove(tmp.size() - 1);

        }
    }

    public static void main(String[] args) {
        dfs(0, 4, 3, a, new ArrayList<Integer>());
        System.out.println(list);
    }
}


[[1, 3, 5], [1, 3, 7], [1, 5, 7], [3, 5, 7]]

 1 //有重复字符的全排列
 2 
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 const int N=1e3+9;
10 char s[N],buf[N];
11 int l;
12 bool vis[N];
13 void dfs(int num){
14     if(num==l){
15         printf("%s\n",buf);
16         return  ;
17     }
18     for(int i =0;i<l;i++){
19         if(!vis[i]){
20             int j;
21             for(j=i+1;j<l;j++){
22                 if(vis[j]&&s[i]==s[j]){//重复:先用了s靠后的字符又满足字符一样 
23                     break;
24                 }
25             }
26             if(j==l){
27                 vis[i]=1;
28                 buf[num]=s[i];
29                 dfs(num+1);
30                 vis[i]=0;
31             }
32         }
33     }
34     
35 }
36 int  main()
37 {
38     while(~scanf("%s",s)){
39         memset(vis,0,sizeof(vis));
40         l =strlen(s);
41         buf[l]='\0';
42         dfs(0);
43     }
44     return 0;
45 }
46 
47 
48 
49 112
51 121
52 211

 

 

class Solution {
    boolean vis[]  =new boolean[9];
    int n;
    List<List<Integer>>list  = new ArrayList<List<Integer>>();
    void dfs(int num,int nums[],ArrayList<Integer>a){
          if(num==n){        
             list.add(new ArrayList<Integer>(a));
          }
          for(int i=0;i<n;i++){
              int j;
              if(!vis[i]){
                  for( j=i+1;j<n;j++) {
                      if(vis[j]&&nums[j]==nums[i])  break;
                  }
                  if(j==n){
                  vis[i]  =true;
                  a.add(nums[i]);
                  dfs(num+1,nums,a);
                  a.remove(a.size()-1);
                  vis[i]  =false;
                  }
              }
          }
    }
    public List<List<Integer>> permuteUnique(int[] nums) {
        n = nums.length;
        dfs(0,nums,new ArrayList<Integer>());
        return list;
    }
}

 

 

 1 //hdu   1016
 2 
 3 
 4 
 5 #include <cstdio>
 6 #include <cstdlib>
 7 #include <cstring>
 8 #include <iostream>
 9 #include <algorithm>
10 using namespace std;
11 const int N=1e2+9;
12 int n;
13 bool vis[N];
14 int a[N];
15 bool prime(int n){
16     if(n==1) return false;
17     for(int i =2;i*i<=n;i++){
18         if(n%i==0) return  false;
19     }
20     return true;
21 }
22 void  dfs(int num,int n){
23     if(num==n&&prime(1+a[n-1])){
24         for(int i =0;i<n;i++){
25             printf("%d%c",a[i],i==n-1?'\n':' ');
26         }
27         return ;
28     }
29     for(int   i=2;i<=n;i++){//1一定是第一个 
30         if(!vis[i]&&prime(i+a[num-1])){
31             vis[i]=1;
32             a[num]=i;
33             dfs(num+1,n);
34             vis[i]=0;
35         }
36     }
37 }
38 int f=1; 
39 int main()
40 {
41     while(~scanf("%d",&n)){
42         memset(vis,0,sizeof(vis));
43         a[0]=1;
44         printf("Case %d:\n",f++);
45         dfs(1,n);
46         printf("\n");
47     }
48     return 0;
49 }

 

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<vector>
 7 #include <cstdlib>
 8 #include <map>
 9 using namespace std;
10 #define mem(a,b) memset(a,b,sizeof(a))
11 const int N = 2e5+5;
12 pair<int,int>P;
13 vector<int> ve[N];
14 vector<pair<int,int> > que[N];
15 int  a[N],b[N];
16 int m;
17 int n,sum;
18 bool vis[N];
19 int cnt  = 0;
20 map<int,int>mp;
21 //从数组b里面取出若干个数,令其和为110 
22 void dfs(int num,int n){
23     {
24         if(num<=n&&sum==110) 
25         {
26             
27             
28 
29         
30     
31         
32             
33         
34             for(int j=1;j<=num-1;j++){
35                 printf("%d ",a[j]);
36             }
37             printf(":: %d \n",sum);
38         
39             return ;
40         }
41         for(int i =mp[a[num-1]]+1;i<=n;i++){
42             if(!vis[i]){
43                 vis[i] = 1;
44                 a[num]= b[i];
45                 sum+=b[i];    
46                 dfs(num+1,n);
47                 vis[i] = 0;
48                 sum-=b[i];
49             }
50         }
51     }
52 }
53 int main()
54 { 
55  sum =0;
56  mp[0]=0;
57 // scanf("%d%d",&n,&m);
58 scanf("%d",&n);
59 for(int i =1;i<=n;i++){
60     scanf("%d",&b[i]);
61     mp[b[i]] =i;
62 }
63     dfs(1,n);
64     return 0;
65 } 

 

子集

78. 子集

难度中等

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

 

示例 1:

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

输入:nums = [0]
输出:[[],[0]]
 

提示:

1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int n =nums.length;
         int ans  = 1<<n;
         List<List<Integer>>list  =new ArrayList<List<Integer>>();
         ArrayList<Integer>t =new ArrayList<Integer>();
         for(int mask=0;mask<ans;mask++){
             t.clear();
             for(int i=0;i<n;i++){
              if ((mask & (1 << i)) !=0) {//!=0大于0
            t.add(nums[i]);
             }
             }
             list.add(new ArrayList<Integer>(t));//new 
         }
         return list;
    }
}

 

class Solution {
    List<List<Integer>>list  =new ArrayList<List<Integer>>();
    int n;
    void dfs(int []nums,int i,ArrayList<Integer>tmp){
        list.add(new ArrayList<>(tmp));
        for(int j=i;j<n;j++){     
                tmp.add(nums[j]);//
                dfs(nums,j+1,tmp);
                tmp.remove(tmp.size()-1);//不用
        }
    }
    public List<List<Integer>> subsets(int[] nums) {
              n = nums.length;
              dfs(nums,0,new ArrayList<Integer>());
              return list;
    }
}

90. 子集 II

难度中等

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

 

示例 1:

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

示例 2:

输入:nums = [0]
输出:[[],[0]]

 

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10

 

class Solution {
  public List<List<Integer>> subsetsWithDup(int[] nums) {
        int n =nums.length;
         int ans  = 1<<n;
         Arrays.sort(nums);
         List<List<Integer>>list  =new ArrayList<List<Integer>>();
         ArrayList<Integer>t =new ArrayList<Integer>();
          boolean flag  =false;
         for(int mask=0;mask<ans;mask++){
             t.clear();
             flag  =false;
             for(int i=0;i<n;i++){
                  
              if ((mask & (1 << i)) !=0) {

               if (i>0&&((mask & (1 << (i-1))) ==0)&&nums[i-1]==nums[i])  {
                   flag  = true;
                   break;
               }
                t.add(nums[i]);
             }
             }
             if(flag==false)
                 list.add(new ArrayList<Integer>(t));
         }
         return list;
    }
}

 

class Solution {
    List<List<Integer>>list  =new ArrayList<List<Integer>>();
    int n;
    void dfs(int []nums,int i,ArrayList<Integer>tmp){
        list.add(new ArrayList<>(tmp));
        for(int j=i;j<n;j++){
             if( j!=i&&nums[j] == nums[j - 1]){
                continue;                                                                                                 
            }
                tmp.add(nums[j]);//
                dfs(nums,j+1,tmp);
                tmp.remove(tmp.size()-1);//不用
        }
    }
    public List<List<Integer>> subsetsWithDup(int[] nums) {
              n = nums.length;
              Arrays.sort(nums);
              dfs(nums,0,new ArrayList<Integer>());
              return list;
    }
}

 

39. 组合总和

难度中等

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

 

 dfs 所有情况,每个可用多次。往前枚举

class Solution {
    List<List<Integer>>list  =new ArrayList<>();
    int n;
     
    void dfs(int num,int []candidates,int target,ArrayList<Integer>tmp){
       
        if(target==0){
            list.add(new ArrayList<Integer>(tmp));
          
            return ;
        }
        for(int i =num;i<n;i++){
             if(target-candidates[i]<0)  break;//因为已经排序,后面更不可能。所以break
            tmp.add(candidates[i]);
           
             dfs(i,candidates,target-candidates[i],tmp);//还是i 因为每个可以用多次
           
             tmp.remove(tmp.size()-1);
              
        }
    }
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
              n  =candidates.length;
              Arrays.sort(candidates);
              dfs(0,candidates,target,new ArrayList<Integer>());
            
              return list;
    }
}

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

 解集不能包含重复的组合。

 

class Solution {
    List<List<Integer>>list  =new ArrayList<>();
    int n;
   boolean vis[];
    void dfs(int num,int []candidates,int target,ArrayList<Integer>tmp){
       
        if(target==0){
           
                   list.add(new ArrayList<Integer>(tmp));
            
            return ;
        }
        
        for(int i =num;i<n;i++){
             if(target-candidates[i]<0)  break;//因为已经排序,后面更不可能。所以break
             if(i>=1&&candidates[i]==candidates[i-1]&&!vis[i-1]) continue ;
            tmp.add(candidates[i]);
            vis[i]  =true;
           
             dfs(i+1,candidates,target-candidates[i],tmp);//还是i 因为每个可以用多次
           
             tmp.remove(tmp.size()-1);
             vis[i]  =false;
              
        }
    }
   public List<List<Integer>> combinationSum2(int[] candidates, int target) {
              n  =candidates.length;
              vis  =new boolean[n+1];
              Arrays.sort(candidates);
              dfs(0,candidates,target,new ArrayList<Integer>());
            
              return list;
    }
}

 

 

 

posted on 2019-03-09 21:46  cltt  阅读(200)  评论(0编辑  收藏  举报

导航