【lc刷题 day13】递归/回溯

BM55 没有重复项数字的全排列 medium

import java.util.*;

public class Solution {
    ArrayList<ArrayList<Integer>> res=new ArrayList<>();
    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        boolean[] visited=new boolean[num.length];
        dfs(num,visited,new ArrayList<>());
        return res;
    }
    void dfs(int[] num,boolean[] visited,ArrayList<Integer> list){
        if(list.size()==num.length){
            res.add(new ArrayList<>(list));
            return;
        }
        for(int i=0;i<num.length;i++){
            if(visited[i]) continue;
            visited[i]=true;
            list.add(num[i]);
            dfs(num,visited,list);
            visited[i]=false;
            list.remove(list.size()-1);
        }
    }
}

深度优先搜索和回溯的思想
时间复杂度O(n!),空间复杂度O(n!)

BM56 有重复项数字的全排列 medium

import java.util.*;

public class Solution {
    ArrayList<ArrayList<Integer>> res=new ArrayList<>();
    public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
        boolean[] visited=new boolean[num.length];
        Arrays.sort(num);
        dfs(num,visited,new ArrayList<>());
        return res;
    }
    void dfs(int[] num,boolean[] visited,ArrayList<Integer> list){
        if(list.size()==num.length){
            res.add(new ArrayList<>(list));
            return;
        }
        for(int i=0;i<num.length;i++){
            if(visited[i]) continue;
            if(i>0&&num[i-1]==num[i]&&!visited[i-1]) continue;
            visited[i]=true;
            list.add(num[i]);
            dfs(num,visited,list);
            visited[i]=false;
            list.remove(list.size()-1);
        }
}
}

与上一道题的区别是要去重
方法是现将num排序
在dfs函数中,如果i>0&&num[i-1]==num[i]&&!visited[i-1]则跳过此次深度优先搜索
1,2(1) 这时要写入2(2)的时候,是不能跳过的,因此添加条件!visited[i-1]
但是如果是1,2(2) 此时是需要跳过的

BM57 岛屿数量

import java.util.*;


public class Solution {
    /**
     * 判断岛屿数量
     * @param grid char字符型二维数组 
     * @return int整型
     */
    public int solve (char[][] grid) {
        // write code here
        boolean[][] visited=new boolean[grid.length][grid[0].length];
        int res=0;
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[0].length;j++){
                if(grid[i][j]=='1'&&!visited[i][j]){
                    mark(i,j,grid,visited);
                    res++;
                }
            }
        }
        return res;
    }
    void mark(int i,int j,char[][] grid,boolean[][] visited){
        if(i!=0&&grid[i-1][j]=='1'&&!visited[i-1][j]){
            visited[i-1][j]=true;
            mark(i-1,j,grid,visited);
        }
        if(i!=grid.length-1&&grid[i+1][j]=='1'&&!visited[i+1][j]){
            visited[i+1][j]=true;
            mark(i+1,j,grid,visited);
        }
        if(j!=0&&grid[i][j-1]=='1'&&!visited[i][j-1]){
            visited[i][j-1]=true;
            mark(i,j-1,grid,visited);
        }
        if(j!=grid[0].length-1&&grid[i][j+1]=='1'&&!visited[i][j+1]){
            visited[i][j+1]=true;
            mark(i,j+1,grid,visited);
        }
    }
}

一个visited[][]数组,开始遍历

BM58 字符串的排列

import java.util.ArrayList;
import java.util.HashSet;
public class Solution {
    HashSet<String> tmp=new HashSet<>();
    public ArrayList<String> Permutation(String str) {
       if(str==null||str.length()==0) return null;
       boolean[] visited=new boolean[str.length()];
       dfs(str,visited,"");
       ArrayList<String> res=new ArrayList<>(tmp);
       return res;
    }
    void dfs(String str, boolean[] visited, String s){
        if(s.length()==str.length()){
            tmp.add(s);
        }
        for(int i=0;i<str.length();i++){
            if(visited[i]) continue;
            visited[i]=true;
            s+=String.valueOf(str.charAt(i));
            dfs(str,visited,s);
            visited[i]=false;
            s=s.substring(0,s.length()-1);
        }
    }
}

使用HashSet去重
//ArrayList res=new ArrayList<>(tmp);
此句将HashSet转换为ArrayList

BM59 N皇后问题 hard

import java.util.*;


public class Solution {
    /**
     * 
     * @param n int整型 the n
     * @return int整型
     */
     Set<Integer> column=new HashSet<>();//标记列不可用
     Set<Integer> posSlant=new HashSet<>();//标记正斜线不可用
     Set<Integer> conSlant=new HashSet<>();//标记反斜线不可用

     int res=0;
    public int Nqueen (int n) {
        // write code here
        compute(0,n);
        return res;
    }
    void compute(int i,int n){
        if(i==n){
            res++;
            return;
        }
        for(int j=0;j<n;j++){
            if(column.contains(j)||posSlant.contains(i-j)||conSlant.contains(i+j)){
                continue;
            }
            column.add(j);
            posSlant.add(i-j);
            conSlant.add(i+j);
            compute(i+1,n);
            column.remove(j);
            posSlant.remove(i-j);
            conSlant.remove(i+j);
        }
    }
}

大名鼎鼎的N皇后问题
时间复杂度O(N!),空间复杂度O(N)
有三个hashset,分别记录列,正斜线和反斜线
i-j可以确定唯一一条正斜线,i+j可以确认唯一一条反斜线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值