暴搜,回溯,剪枝

力扣77.组合暴搜,回溯,剪枝_第1张图片

class Solution {
    List>ret=new ArrayList<>();
    Listpath=new ArrayList<>();
    int n; int k;
    public List> combine(int _n, int _k) {
        n=_n;
        k=_k;
     dfs(1);
     return ret;
    }
    public void dfs(int pos){
        if(path.size()==k){
            ret.add(new ArrayList<>(path));
            return ;
        }
        //模拟画递归图的时候,有个地方没有思考清楚,就是加入说他刚开始是1,2,那么还会出现一次1,2,我刚开始想
        //这怎么能对呢,明明1,2重复了
        //后来才想到,是回溯想错了,应该是当他回溯的时候,就回到原先的dfs处,所以当他1,2存完之后,他是i还是2
        
        for(int i=pos;i<=n;i++){
            path.add(i);
            dfs(i+1);
            path.remove(path.size()-1);
        }
        }
    }

力扣494.目标和

暴搜,回溯,剪枝_第2张图片

暴搜,回溯,剪枝_第3张图片

刚开始我一直在思考一件事,就是我的薄弱代码能力,怎么表示加号和减号

后来发现,其实发现这就是我的思维和编程思维的区别

我的思维总在想把符号添加到数字身上,如何如何,其实编程的思维体现在哪,就是说这种加不加符号,完全可以转化成——运算符的加减法

假如说是加号,那就是两数相加,假如说减号那么就是两数字相减

class Solution {
    int ret;
    int sum;
    int path;
    public int findTargetSumWays(int[] nums, int target) {
    path=target;
    dfs(nums,0);
    return ret;
    }
    public void dfs(int []nums,int pos){
    if(pos==nums.length){
    if(path==sum){
        ret++;
    }
        return ;
    }
    sum+=nums[pos];
    dfs(nums,pos+1);
    sum=sum-nums[pos];

    sum=sum-nums[pos];
    dfs(nums,pos+1);
    sum+=nums[pos];
    }
}

全局变量写成参数的写法(这个时候就不用回溯了,怎么选择使用看自己,代码简洁,就是把记录全部数字当成参数)

class Solution {
    int ret;
    int path;
    public int findTargetSumWays(int[] nums, int target) {
    path=target;
    dfs(nums,0,0);
    return ret;
    }
    public void dfs(int []nums,int pos,int sum){
    if(pos==nums.length){
    if(path==sum){
        ret++;
    }
        return ;
    }
    dfs(nums,pos+1,sum+nums[pos]);
    dfs(nums,pos+1,sum-nums[pos]);
    }
}

力扣39.组合总和

暴搜,回溯,剪枝_第4张图片

剪枝只需要剪掉这个位置之前的位置即可,从pos开始,剪枝完成

然后递归是递归的下标

class Solution {
    List>ret=new ArrayList<>();
    Listpath=new ArrayList<>();
    int sum;
    int k;
public List> combinationSum(int[] candidates, int target) {
        k=target;
        dfs(candidates,0);
        return ret;
    }
public void dfs(int[]candidates,int pos){
    if(sum==k){
        ret.add(new ArrayList<>(path));
        return;
    }
    if(sum>k){
        return;
    }
    //这个操作for是横着走
    for(int i=pos;i

这个是吧sum当成参数而不是全局变量

class Solution {
    List>ret=new ArrayList<>();
    Listpath=new ArrayList<>();
    int k;
public List> combinationSum(int[] candidates, int target) {
        k=target;
        dfs(candidates,0,0);
        return ret;
    }
public void dfs(int[]candidates,int pos,int sum){
    if(sum==k){
        ret.add(new ArrayList<>(path));
        return;
    }
    if(sum>k){
        return;
    }
    //这个操作for是横着走
    for(int i=pos;i

解法2:

class Solution {
    List>ret=new ArrayList<>();
    Listpath=new ArrayList<>();
    int k;
public List> combinationSum(int[] candidates, int target) {
        k=target;
        dfs(candidates,0,0);
        return ret;
    }
public void dfs(int[]candidates,int pos,int sum){
    if(sum==k){
        ret.add(new ArrayList<>(path));
        return;
    }
    if(sum>k||pos==candidates.length){
        return;
    }
    //这个操作for是横着走,pos来做下标
    for(int i=0;i*candidates[pos]+sum<=k;i++){
    if(i!=0)path.add(candidates[pos]);
    dfs(candidates,pos+1,sum+i*candidates[pos]);
       }
       //回溯是把哪个情况列举完,再去恢复现场
       //恢复现场
    for(int i=1;i*candidates[pos]+sum<=k;i++){
           path.remove(path.size()-1);
       }   
    }
}

力扣784.字母大小写全排列
暴搜,回溯,剪枝_第5张图片暴搜,回溯,剪枝_第6张图片

我的代码能力还是弱,但是能知道他的一些思想,确实画出图来,更容易去想

首先先说我的第一个困扰,就是字符串操作,我不是很会用字符串,因为他的各个方法已经一些东西,她这个转换成大写,我以为是在字符串上操作,没想到仅仅是我使用 

 char ch=s.charAt(pos);  使用一个字符,然后存储的是字符,pos在这里代表下标,

其次第二个困扰:怎么判断他是数字还是字符,我开始是想用ascll码,但是我又想到ascll也是数字,然后我也开始想过0-9但是我又否认了,因为我在想数字假如说是11,这种两位数不久错误了吗,我又突然醒悟,我字符串是一个一个取的,就算三位数111,他也是一个1一个1的取,换句话说数字就只有0-9,那么就是判断字符<0或者>9的时候不合格,然后字符A和a差一律32。

String修改不方便,以后都是使用StringBuffer用来修改字符串

暴搜,回溯,剪枝_第7张图片

class Solution {
    Listret=new ArrayList<>();
    StringBuffer path=new StringBuffer();
    public List letterCasePermutation(String s) {
    dfs(s,0);
    return ret;
    }
    public void dfs(String s,int pos){
    if(path.length()==s.length()){
       ret.add(path.toString());
       return ;
   }
   char ch=s.charAt(pos);
//不发生改变
path.append(ch);
dfs(s,pos+1);
path.deleteCharAt(path.length()-1);

if(ch<'0'||ch>'9'){
//发生改变
if(ch>='a'&&ch<='z'){
    ch-=32;
}else{
    ch+=32;
}
       path.append(ch);
       dfs(s,pos+1);
      path.deleteCharAt(path.length()-1);
       }
    }
}

你可能感兴趣的:(深度优先,算法)