zoukankan      html  css  js  c++  java
  • 算法之回溯和随机

    算法之回溯

    精髓就是想象一个蜗牛的角,碰到危险回退回去,再换个方向试探,一般深度尽量用递归做,别怕,递归思想才是王道。

    技巧就是只有一个临时变量,只有当临时变量是目标 值的时候才new出来,插到总结果当中去。否则看正规代码时,会卡壳。

    自己总结的书写规则,基本上套用是没有问题的。
    //参数:下一深度,深度选择和总深度,临时数据,结果
    //1.1 符合结果的断枝:把临时数据新创建一份,加入到结果中。
    //1.2 看看是否还有任何其他不符合断枝情况。
    //2.1 不断枝情况:是否需要处理下0深度。 
    //2.2 列出所有分支,并每次进行回退。
    //非重复的组合,一个深度只出现一个元素,那么可以保证组合中不重复元素,至于怎么分支看情况。

    //按键组合。

    class Solution 
    {
        //考察深度优先
        private Map<Character,List<Character>> mapchar;
    
        public List<String> letterCombinations(String digits) 
        {
            initlist();
            List<String> res=new  ArrayList<String>();
            
            if(digits.length()==0)
            {
                return res;
            }
            else
            {
                StringBuilder explorer=new StringBuilder();
                DFS(0,digits,explorer,res);
                return res;
            }
        }
        
        //参数:下一深度,深度选择和总深度,临时数据,结果
        //1 断枝:超过最大深度或无效情况,把临时数据新创建一份,加入到结果中。
        //2.1 是否需要处理下0深度。 
        //2.2 列出所有分支,并每次进行回退。
        private void DFS(int depth,String digits,StringBuilder explorer,List<String> res)
        {
            if(depth>digits.length())//1 断枝:超过最大深度或无效情况
            {
                res.add(explorer.toString());
            }
            else if(depth<=digits.length())
            {
                if(depth==0)//2.1 是否需要处理下0深度
                {
                    DFS(1,digits,explorer,res);
                }
                else
                {
                    List<Character> allChar=getList(digits.charAt(depth-1));
                    for(int i=0;i<allChar.size();i++)//2.2 列出所有分支,并每次进行回退。
                    {
                        explorer.append(allChar.get(i));
                        DFS(depth+1,digits,explorer,res);
                        explorer.delete(explorer.length()-1,explorer.length());
                    }
                }
            }
        }
        
        private List<Character> getList(char a)
        {
            return mapchar.get(a);
        }
        
        private void initlist()
        {
            mapchar=new HashMap();
            
            List<Character> list2= new ArrayList<Character>();
            list2.add('a');
            list2.add('b');
            list2.add('c');
            mapchar.put('2',list2);
            
            List<Character> list3= new ArrayList<Character>();
                list3.add('d');
                list3.add('e');
                list3.add('f');
            mapchar.put('3',list3);
            
    
            List<Character> list4= new ArrayList<Character>();
            list4.add('g');
            list4.add('h');
            list4.add('i');
            mapchar.put('4',list4);
            
        List<Character> list5= new ArrayList<Character>();
                list5.add('j');
                list5.add('k');
                list5.add('l');
            mapchar.put('5',list5);
            
            List<Character> list6= new ArrayList<Character>();
    list6.add('m');
                list6.add('n');
                list6.add('o');
            mapchar.put('6',list6);
            
            List<Character> list7= new ArrayList<Character>();
                list7.add('p');
                list7.add('q');
                list7.add('r');
                list7.add('s');
            mapchar.put('7',list7);
            
            List<Character> list8= new ArrayList<Character>();
                list8.add('t');
                list8.add('u');
                list8.add('v');
            mapchar.put('8',list8);
            
            
            List<Character> list9= new ArrayList<Character>();
                list9.add('w');
                list9.add('x');
                list9.add('y');
                list9.add('z');
            mapchar.put('9',list9);
            
    
        }
    }
    class Solution {
        public List<List<Integer>> combinationSum2(int[] candidates, int target) 
        {
            Arrays.sort(candidates);
            List<Integer> explorer=new LinkedList<Integer>();
            
            List<List<Integer>> res=new ArrayList<List<Integer>>();
            
            dfs(0,candidates,explorer,0,target,res);
            
            return res;
        }
        
        
        //参数:下一深度,深度选择和总深度,临时数据,结果
        //1.1 断枝:下次深度刚刚比最大大一,且符合结果,把临时数据新创建一份,加入到结果中。
        //1.2 看看是否还有任何其他断枝情况。
        //2.1 不断枝情况:是否需要处理下0深度。 
        //2.2 列出所有分支,并每次进行回退。
        private void dfs(int depth,int[] candidates,List<Integer> explorer,int explorerSum,int target,List<List<Integer>> res)
        {
            if(depth<=candidates.length+1 && explorerSum==target)//1 断枝:超过最大深度或无效情况,把临时数据新创建一份,加入到结果中.这里断枝加数据还需要检测
            {
                if(!Check(explorer,res))
                {
                    res.add(new ArrayList<Integer>(explorer));
                }
            }
            else if(depth>candidates.length+1 || explorerSum>target)//1 断枝:超过最大深度或无效情况,把临时数据新创建一份,加入到结果中.这里断枝加数据还需要检测
            {
                
            }
            else if(depth<candidates.length+1)//2.2 列出所有分支,并每次进行回退。这里任何分支都有可能断指。
            {
                if(depth==0)
                {
                    dfs(1,candidates,explorer,0,target,res);
                }
                else
                {
                    explorer.add(candidates[depth-1]);
                    dfs(depth+1,candidates,explorer,explorerSum+candidates[depth-1],target,res);
                    explorer.remove(explorer.size()-1);
                    dfs(depth+1,candidates,explorer,explorerSum,target,res);
                }
            }
        }
        
        private boolean Check(List<Integer> explorer,List<List<Integer>> res)
        {
            boolean check=false;
            
            List<Integer> explorer2=new ArrayList<Integer>(explorer);
            Collections.sort(explorer2);
            
            
            for(int i=0;i<res.size();i++)
            {
                List<Integer> cc2=new ArrayList<Integer>(res.get(i));
                Collections.sort(cc2);
                
                if(cc2.size()==explorer2.size())
                {
                    int k=0;
                    for(k=0;k<cc2.size();k++)
                    {
                        if(cc2.get(k)!=explorer2.get(k))
                        {
                            break;
                        }
                    }
                    if(k==res.get(i).size())
                    {
                        check=true;
                        break;
                    }
                }
            }
            return check;
        }
    }
  • 相关阅读:
    媒体查询
    H5 progress标记
    sqlite数据库常用语句
    C#导出Word文档开源组件DocX
    bat实现监控进程守护程序-保证平台服务的稳定执行
    windows开机自动执行bat脚本启动cmd命令窗口并执行命令,最后自动关闭cmd命令窗
    Python实现定时执行任务的三种方式简单示例
    bat实现守护程序保证平台正常运行
    Windows CMD命令大全
    Windows下使用批处理文件.bat删除旧文件
  • 原文地址:https://www.cnblogs.com/lsfv/p/10514875.html
Copyright © 2011-2022 走看看