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可以确认唯一一条反斜线