zoukankan      html  css  js  c++  java
  • 全排列 -深度优先算法中的剪枝问题

    在深度优先算法中,如果遇到需要剪枝的问题,如果你不剪,必然会爆内存,爆栈。

    看以下的题目:

    给出一个字符串S(可能有重复的字符),按照字典序从小到大,输出S包括的字符组成的所有排列。例如:S = "1312",
    输出为:
     
    1123
    1132
    1213
    1231
    1312
    1321
    2113
    2131
    2311
    3112
    3121
    3211

    Input输入一个字符串S(S的长度 <= 9,且只包括0 - 9的阿拉伯数字)Output输出S所包含的字符组成的所有排列Sample Input

    1312

    Sample Output

    1123
    1132
    1213
    1231
    1312
    1321
    2113
    2131
    2311
    3112
    3121
    3211
    题目看起来很简单,似乎是个水题,但是,你不剪枝就出错。
    错误解法:用一个数组来保存结果.
    实现代码:
    package KingLong;

    import java.util.Arrays;
    import java.util.Scanner;

    public class Main
    {
        static final int MAX = 10;
        static int num[] = new int[MAX];
        static boolean vis[] = new boolean[MAX];
        static int len;
        public static void main(String []args)
        {
            Scanner cin = new Scanner(System.in);
            String str = cin.next();
            len = str.length();
            for(int i = 0 ; i < len ; i++)
            {
                num[i] = str.charAt(i)-'0';
            }
            Arrays.sort(num,0,len);
            dfs(0,"");
        }
        static void dfs(int cnt,String str)
        {
            if(cnt == len)
            {
                System.out.println(str);
                return;
            }
            for(int i = 0 ; i < len ; i++)
            {
                if(vis[i] == false)
                {
                    vis[i] = true;
                    dfs(cnt+1,str+num[i]);
                    vis[i] = false;
                    while(i < len && num[i] == num[i+1])
                    {
                        i++;
                    }
                }
            }
        }
    }
    结果爆栈了,气人啊。
    剪枝的方法:
    package KingLong;

    import java.util.Arrays;
    import java.util.Scanner;

    public class Main
    {
    static final int MAX = 10;
    static int num[] = new int[MAX];
    static boolean vis[] = new boolean[MAX];
    static int len;
    public static void main(String []args)
    {
    Scanner cin = new Scanner(System.in);
    String str = cin.next();
    len = str.length();
    for(int i = 0 ; i < len ; i++)
    {
    num[i] = str.charAt(i)-'0';
    }
    Arrays.sort(num,0,len);
    dfs(0,"");
    }
    static void dfs(int cnt,String str)
    {
    if(cnt == len)
    {
    System.out.println(str);
    return;
    }
    for(int i = 0 ; i < len ; i++)
    {
    if(vis[i] == false)
    {
    vis[i] = true;
    dfs(cnt+1,str+num[i]);
    vis[i] = false;
    while(i < len && num[i] == num[i+1])//这个是最重要的一步
    {
    i++;
    }
    }
    }
    }
    }

    import java.util.Arrays; import java.util.Scanner; publicclass Main { staticfinalint MAX = 10; staticint num[] = newint[MAX]; staticboolean vis[] = newboolean[MAX]; staticint len; public static void main(String []args) { Scanner cin = new Scanner(System.in); String str = cin.next(); len = str.length(); for(int i = 0 ; i < len ; i++) { num[i] = str.charAt(i)-'0'; } Arrays.sort(num,0,len); dfs(0,""); } static void dfs(int cnt,String str) { if(cnt == len) { System.out.println(str); return; } for(int i = 0 ; i < len ; i++) { if(vis[i] == false) { vis[i] = true; dfs(cnt+1,str+num[i]); vis[i] = false; while(i < len && num[i] == num[i+1]) { i++; } } } } }

  • 相关阅读:
    [转载]JavaScript世界的一等公民 函数
    JavaScript基础知识词法结构
    JavaScript触发asp.net服务器端控件事件
    WinForm窗体间传值大全
    快速导入Excel
    让虚拟机支持USB HDD 启动
    常见的mysql导出excel工具介绍
    silverlight 播放器,丑丑版
    快速导出Excel
    一个C#编写QQ接口软件QQ协议(转)
  • 原文地址:https://www.cnblogs.com/674001396long/p/9798238.html
Copyright © 2011-2022 走看看