回溯法:
第几个全排列
括号组合
下一个排列
数字组合
矩阵中对应字符串
矩阵的XO替换
广度优先遍历:字符串字典转换:字符串字典匹配
岛屿问题:
图树判断
门问题
第几个全排列:
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
“123”
“132”
“213”
“231”
“312”
“321”
给定 n 和 k,返回第 k 个排列。
说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。
示例 1:
输入: n = 3, k = 3
输出: “213”
示例 2:
输入: n = 4, k = 9
输出: “2314”
解析:最开始的时候使用的是遍历出所有全排列,再得到第几个排列输出。
核心代码
if(flag[i]==0){
c[len]=(char)('0'+i+1);
flag[i]=1;
getTotalOrdering(len+1,flag,c,k);
falg[i]=0;
}
但是遗憾的是超出了时间限制,所以想到剪枝的方法(虽然是很难剪)。
思想是当第i个数字插入a后,其之后n-i数字对应的排列顺序是(n-i)!
如果k>(n-i)!,说明想要的情况不在第i个数字插入a的情况里,所以直接continue
注意到这个算法已经不是回溯算法了(一插到底直接return)所以falg[i]=0;不用再回设。
且throw new RuntimeException(“参数错误”);代替return,因为如果不这样做则函数没有不判断的return语句,是无法编译通过的(但是如果你参数正确其实不会执行到这步)
class Solution {
List<String> list=new LinkedList<>();
public String getPermutation(int n, int k) {
int flag[]=new int[n];
char c[]=new char[n];
return this.getTotalOrdering(0,flag,c,k);
}
public String getTotalOrdering(int len,int flag[],char c[],int k){
if(len==flag.length){return String.valueOf(c);}
for(int i=0;i<flag.length;i++){
if(flag[i]==0){
int ThisOrderingNum=getThisOrderingNum(flag.length-len-1);
if(k>ThisOrderingNum){
k=k-ThisOrderingNum;
continue;}
c[len]=(char)('0'+i+1);
flag[i]=1;
return getTotalOrdering(len+1,flag,c,k);
}
}
throw new RuntimeException("参数错误");
}
public int getThisOrderingNum(int len){
int sum=1;
if(len==0)return sum;
for(int i=len;i>0;i--){
sum*=i;
}
return sum;
}
}
括号组合
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
例如,给出 n = 3,生成结果为:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
class Solution {
List<String>list=new LinkedList<>();
public List<String> generateParenthesis(int n) {
addParenthesis("",n,n);
return list;
}
public void addParenthesis(String str,int a,int b){
if(b==0)list.add(str);
else{
if(a<b)addParenthesis(str+')',a,b-1);
if(a>0)addParenthesis(str+'(',a-1,b);
}
}
}
下一个排列
leetcode31
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
import java.util.*;
import java.lang.*;
class Solution {
public void nextPermutation(int[] nums) {
int i,j;
for(i=nums.length-1;i>=1&&nums[i]<=nums[i-1];i--);
if(i>0){
int k=i-1;
for(j=nums.length-1;j>k&&nums[j]<=nums[k];j--);
swap(nums,k,j);
}
reverse(nums,i);
}
private void reverse(int[] nums, int start) {
int i = start, j = nums.length - 1;
while (i < j) {
swap(nums, i, j);
i++;