前言
回溯算法
一、电话号码的组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
class Solution {
List<String> list = new ArrayList<>();
String[] letter_map = {" ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public List<String> letterCombinations(String digits) {
if(digits.length()==0||digits==null){
return new ArrayList<>();
}
dfs(digits,new StringBuilder(),0);
return list;
}
private void dfs(String digits,StringBuilder s,int index){
if(index==digits.length()){
list.add(s.toString());
return;
}
char c=digits.charAt(index);
int ii=c-'0';
String tmp = letter_map[ii];
for(int i =0;i<tmp.length();i++){
s.append(tmp.charAt(i));
dfs(digits,s,index+1);
s.deleteCharAt(s.length()-1);
}
}
}
二、括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
有效括号组合需满足:左括号必须以正确的顺序闭合。
class Solution {
List<String> list = new ArrayList<>();
public List<String> generateParenthesis(int n) {
if(n<1){
return list;
}
dfs(n,0,0,"");
return list;
}
private void dfs(int n,int left,int right,String s){
if(right>left||right>n||left>n){
return;
}
if(s.length()==2*n){
list.add(s);
return;
}
dfs(n,left+1,right,s+"(");
dfs(n,left,right+1,s+")");
}
}
三、全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
class Solution {
List<List<Integer>> list = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
if(nums==null||nums.length==0){
return new ArrayList<>();
}
int[] flag = new int[nums.length];
ArrayList<Integer> res = new ArrayList<>();
dfs(res,nums,flag,0);
return list;
}
private void dfs(List<Integer> res,int[] nums,int[] flag,int index){
if(index==nums.length){
list.add(new ArrayList(res));
return;
}
for (int i = 0; i < nums.length; i++) {
if(flag[i]==1){continue;}
flag[i]=1;
res.add(nums[i]);
dfs(res,nums,flag,index+1);
flag[i]=0;
res.remove(res.size()-1);
}
}
}
四、子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集
class Solution {
List<List<Integer>> list = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
if(nums==null||nums.length==0){
return new ArrayList<>();
}
ArrayList<Integer> res = new ArrayList<>();
dfs(res,nums,0);
return list;
}
private void dfs(List<Integer> res,int[] nums,int index){
list.add(new ArrayList(res));
if(index==nums.length){
return;
}
for (int i = index; i < nums.length; i++) {
res.add(nums[i]);
dfs(res,nums,i+1);
res.remove(res.size()-1);
}
}
}
五、单词搜索
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
class Solution {
public boolean exist(char[][] board, String word ){
if(board==null||board.length==0){
return false;
}
int m = board.length;
int n = board[0].length;
int[][] flag = new int[m][n];
for (int i = 0; i <m ; i++) {
for (int i1 = 0; i1 < n; i1++) {
boolean b = dfs(board, i, i1, flag, word, 0);
if(b){
return true;
}
}
}
return false;
}
private boolean dfs(char[][] board,int x,int y,int[][] flag,String word,int index){
int m = board.length;
int n = board[0].length;
if(word.charAt(index)!=board[x][y]){
return false;
}else if(index==word.length()-1){
return true;
}
flag[x][y]=1;
boolean res =false;
int[][] de={{1,0},{-1,0},{0,1},{0,-1}};
for (int i = 0; i <=3 ; i++) {
int xi=x+de[i][0];
int yi=y+de[i][1];
if(xi>=m||yi>=n||xi<0||yi<0){
continue;
}
if(flag[xi][yi]==0){
boolean b = dfs(board, xi, yi, flag, word, index + 1);
if(b){
res=true;
break;
}
}
}
flag[x][y]=0;
return res;
}
}
六、分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
class Solution {
List<List<String>> list =new ArrayList<>();
List<String> res =new ArrayList<>();
public List<List<String>> partition(String s) {
dfs(s,0);
return list;
}
private void dfs(String s,int index){
if(index==s.length()){
list.add(new ArrayList(res));
}
for (int i = index; i <s.length() ; i++) {
if(isPartition(s,index,i)){
String s1 = s.substring(index, i + 1);
res.add(s1);
}else{
continue;
}
dfs(s,i+1);
res.remove(res.size()-1);
}
}
private boolean isPartition(String s,int start,int end){
for(int i=start,j=end;i<j;i++,j--){
if(s.charAt(i)!=s.charAt(j)){
return false;
}
}
return true;
}
}