算法 分治与回溯

    科技2024-12-01  17

    分治和回溯其实就是一种更为复杂的递归

    分治代码模板:(与递归模板基本一样)

    def divide_conquer(problem,param1,param2,…):

    recursion terminator

    if problem is None:

    print_result return

    prepare data

    data=propare_data(problem)

    subproblems=split_problem(problem,data)

    #conquer subproblems

    subresult1=self.divide_conquer(subproblems[0],p1,…)

    subresult2=self.divide_conquer(subproblems[1],p1,…)

    subresult3=self.divide_conquer(subproblems[2],p1,…)

    process and generate the final result

    result=process_result(subresult1,subresult2,subresult3,…)

    回溯法就是将问题拆成几个子问题 分步答案不能得到有效的正确解答时 就会上一步甚至几步的运算 再通过其他的分步解答来获得可能的答案

    Pow(x,n)问题 数的平方(分治法)

    public double fastPow(double x, long long n) {

    if (n == 0) return 1.0; double

    half = fastPow(x, n / 2); 将问题分解成子问题 进行解决

    if(n%2==0)

    {

    return

    half * half;

    } else { return

    half * half * x;

    }

    }

    double

    myPow(double x,int n){ 如果n是负数 解决方案

    long

    long N=n;

    if(N<0){ x=1/x; N=-N; } return

    fastPow(x,N);

    }

    寻找子集(递归法)

    public List<List> subsets(int nums[]){

    List<List> res=new ArrayList<>();  前面的准备阶段与之前的判断括号组成合法方式一样

    if(nums==null)  return res;

    dfs(res,nums,new ArrayList,0);  dfs就是一个递归的方法

    return res;

    }

    public void dfs(List<List> res,int [] nums,List list,int index){  这里的index就是访问到递归里的第几层   list代表临时存放数

    if(index==nums.length){}

    res.add(new ArrayList(list));

    return;

    dfs(res,nums,list,index+1);  如果正常不加入数  那么往下走

    list.add(nums[index]);  如果加入数  那么就往里加index指向的层的那个数

    dfs(res,nums,list.copy(),index+1);  加完之后  复制list 接着往下走

    list.remove(list.size()-1);  最后清除临时list里的多余数

    }

    电话号号码的字母组合(递归)

    class Solution{

    public List letterCombinations(String digits){  digits是输入组合号码的字符串

    if(digits==null||digits.length()==0){

    return new ArrayList();

    }

    Map<Character,String> map=new HashMap<Character,String>();

    map.put(‘2’,“abc”);

    map.put(‘3’,“def”);

    map.put(‘4’,“ghi”);

    map.put(‘5’,“jkl”);

    map.put(‘6’,“mno”);

    map.put(‘7’,“pqrs”);

    map.put(‘8’,“tuv”);

    map.put(‘9’,“wxyz”);

    List res=new LinkedList();

    search("",digits,0,res,map);  空字符串s 组合号码 i就是level

    return res;

    }

    private void search(String s,String digits,int i,List res,Map<Character,String> map){

    if(i==digits.length())  res.add(s); 当level到达字符串的最后一个字符时  将结果加入res中

    return;

    String letters=map.get(digits.charAt(i));  level继续往下走  遍历组合号码的字符串

    for(int j=0;j<letters.length();j++){

    search(s+letters.charAt(j),digits,i+1,res,map);

    }

    }

    }

    N皇后

    Processed: 0.016, SQL: 8