public List> permute(int[] nums) {
ArrayList numsArray=new ArrayList();
for(int i:nums){
numsArray.add(i);
}
Collections.sort(numsArray);
List> res=new ArrayList>();
solve(res,numsArray,0);
return res;
}
private void solve(List> res,ArrayList nums,int index){
if(index>=nums.size()){
List permutation=new ArrayList(nums);
res.add(permutation);
}
for(int i=index;i<=nums.size()-1;i++){
Collections.swap(nums, i, index);
solve(res,nums,index+1);
Collections.swap(nums, i, index);
}
}
方案二
public List> permute(int[] nums) {
ArrayList numsArray=new ArrayList();
for(int i:nums){
numsArray.add(i);
}
boolean[] used=new boolean[numsArray.size()];
Collections.sort(numsArray);
List> res=new ArrayList>();
ArrayList subSet=new ArrayList();
solve(res,numsArray,subSet,used);
return res;
}
private void solve(List> res,ArrayList nums,ArrayList subSet,boolean[] used){
if(subSet.size()==nums.size()){
ArrayList clone=new ArrayList(subSet);
res.add(clone);
return;
}
for(int i=0;i
public List> permuteUnique(int[] nums) {
ArrayList numsArray=new ArrayList();
for(int i:nums){
numsArray.add(i);
}
boolean[] used=new boolean[numsArray.size()];
Collections.sort(numsArray);
List> res=new ArrayList>();
ArrayList subSet=new ArrayList();
solve(res,numsArray,subSet,used);
return res;
}
private void solve(List> res,ArrayList nums,ArrayList subSet,boolean[] used){
if(subSet.size()==nums.size()){
ArrayList clone=new ArrayList(subSet);
res.add(clone);
return;
}
for(int i=0;i0&&!used[i-1]&&nums.get(i).equals(nums.get(i-1)))) continue;
subSet.add(nums.get(i));//加入新元素,并递归调用下一个元素
used[i]=true;
solve(res,nums,subSet,used);
subSet.remove(subSet.size()-1);//还原
used[i]=false;
}
}
public void nextPermutation(int[] nums) {
int index=nums.length-1;
//寻找第一对非递减序列
while(index-1>=0&&nums[index-1]>=nums[index]) index--;
if(index==0){
reverse(nums,0,nums.length-1);
return;
}
int smallerIndex=index-1,change=index;
//寻找恰当交换元素
while(change+1nums[smallerIndex])change++;
int t=nums[smallerIndex];nums[smallerIndex]=nums[change];nums[change]=t;
reverse(nums,index,nums.length-1);
}
private void reverse(int[] nums,int begin,int end){
int t;
while(begin
public String getPermutation(int n, int k) {
int[] arr=new int[n+1];
for(int i=1;i<=n;i++){
arr[i]=i;
}
k=(k-1)%factorial(n);
int index=1;
while(k>0){
if(k>=factorial(n-index)){
int change=index+1;
while(arr[change]
分析
我们采用分期摊还的方法,从数字字符串的第一个字符开始扫描,记录之前数字产生的所有组合,然后将当前数字映射的字符附加到之前产生的所有组合中,产生新的结果集。
public List letterCombinations(String digits) {
String[] strMap={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
ArrayList res=new ArrayList();
if(digits.equals("")||digits==null) return res;
res.add("");
for(int i=0;i t=new ArrayList();
for(int j=0;j
public List> combine(int n, int k) {
List> res=new ArrayList>();
int[] nums=new int[n];
ArrayList r=new ArrayList();
boolean[] used=new boolean[n];
for(int i=0;i> res,ArrayList r,int[] nums,int k,boolean[] used){
if(r.size()==k){
ArrayList clone=new ArrayList(r);
res.add(clone);
return ;
}
int index=r.size();
for(int i=index;i
public List> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List> res=new ArrayList>();
ArrayList r=new ArrayList();
solve(res,r,candidates,target,0);
return res;
}
public void solve(List> res,ArrayList r,int[] candidates,int target,int index){
if(target==0){
ArrayList clone=new ArrayList(r);
res.add(clone);
return;
}
if(index>=candidates.length||target
public List> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
List> res=new ArrayList>();
ArrayList r=new ArrayList();
solve(res,r,candidates,target,0);
return res;
}
public void solve(List> res,ArrayList r,int[] candidates,int target,int index){
if(target==0){
ArrayList clone=new ArrayList(r);
res.add(clone);
return;
}
if(index>=candidates.length||target
public List> combinationSum3(int k, int n) {
List> res=new ArrayList>();
ArrayList sub=new ArrayList();
solve(res,sub,k,n,1);
return res;
}
private void solve(List> res,ArrayList sub,int k,int n,int start){
if(sub.size()==k&&n==0){
ArrayList clone=new ArrayList(sub);
res.add(clone);
return;
}
if(n<0||start==10||(sub.size()==k&&n!=0)){
return;
}
//选择当前元素
sub.add(start);
solve(res,sub,k,n-start,start+1);
sub.remove(sub.size()-1);
//不选择当前元素
solve(res,sub,k,n,start+1);
}
public List generateParenthesis(int n) {
List res=new ArrayList();
if(n==0){
res.add("");
return res;
}
StringBuilder r=new StringBuilder();
solve(n,0,0,res,r);
return res;
}
private void solve(int n,int left,int right,List res,StringBuilder r){
if(r.length()==2*n){
System.out.println(r.toString());
res.add(r.toString());
return;
}
if(left
public List> subsets(int[] nums) {
List> res=new ArrayList>();
res.add(new ArrayList());
for(int i=0;i> t=new ArrayList>();
for(List r:res){
t.add(r);
ArrayList clone=new ArrayList(r);
clone.add(nums[i]);
t.add(clone);
}
res=t;
}
return res;
}
public List> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
boolean[] used=new boolean[nums.length];
List> res=new ArrayList>();
ArrayList sub=new ArrayList();
solve(res,0,sub,nums,used);
return res;
}
private void solve(List> res,int start,ArrayList sub,int[] nums,boolean[] used){
if(start==nums.length){
ArrayList clone=new ArrayList(sub);
res.add(clone);
return;
}
//选择当前元素
if(start>0&&nums[start]==nums[start-1]&&!used[start-1]){
//do nothing
}else{
used[start]=true;
sub.add(nums[start]);
solve(res,start+1,sub,nums,used);
sub.remove(sub.size()-1);
used[start]=false;
}
//不选择当前元素
solve(res,start+1,sub,nums,used);
}
public boolean exist(char[][] board, String word) {
boolean used[][]=new boolean[board.length][board[0].length];
for(int i=0;i
思考:如果我们有很多的单词需要查找时,如何避免重复的搜索过程呢?我们可以先建立trie树(单词查找树),然后对trie中的不同路径进行搜索。见leetcode 212 Word Search II
public List> partition(String s) {
List> res=new ArrayList>();
List sub=new ArrayList();
solve(res,sub,s,0);
return res;
}
private void solve(List> res,List sub,String s,int start){
if(start==s.length()){
List clone=new ArrayList(sub);
res.add(clone);
return;
}
List ends=new ArrayList();
for(int i=start;i
public void solveSudoku(char[][] board) {
ArrayList> emptyLocations=
new ArrayList>();
for(int row=0;row<9;row++){
for(int col=0;col<9;col++){
if(board[row][col]=='.'){
ArrayList location=new ArrayList();
location.add(row);location.add(col);
emptyLocations.add(location);
}
}
}
solve(board,0,emptyLocations);
}
private boolean solve(char[][] board,int index,ArrayList> emptyLocations){
if(index==emptyLocations.size()){
return true;
}
ArrayList location=emptyLocations.get(index);
int row=location.get(0),col=location.get(1);
for(char c='1';c<='9';c++){
if(isValid(board,row,col,c)){
board[row][col]=c;
if(solve(board,index+1,emptyLocations)){
return true;
}else{
board[row][col]='.';
}
}
}
return false;
}
public boolean isValid(char[][] board,int row,int col,char c){
//验证行
for(int i=0;i<9;i++){
if(board[row][i]==c)
return false;
}
//验证列
for(int i=0;i<9;i++){
if(board[i][col]==c)
return false;
}
//验证3*3格子
for(int i=(row/3)*3;i<(row/3)*3+3;i++){
for(int j=(col/3)*3;j<(col/3)*3+3;j++){
if(board[i][j]==c)
return false;
}
}
return true;
}
public List> solveNQueens(int n) {
ArrayList locations=new ArrayList();
List> res=new ArrayList>();
solve(res,locations,n);
return res;
}
private void solve(List> res,ArrayList locations,int n){
if(n==locations.size()){
addRes(res,locations);
return;
}
for(int i=0;i locations,int location){
for(int i=0;i> res,ArrayList locations){
List r=new ArrayList();
for(int i=0;i
public List> solveNQueens(int n) {
int[] locations=new int[n+1];
for(int i=1;i<=n;i++){
locations[i]=i;
}
List> res=new ArrayList>();
solve(res,locations,1);
return res;
}
private void solve(List> res,int[] locations,int index){
if(index==locations.length){
addRes(res,locations);
return;
}
for(int i=index;i<=locations.length-1;i++){
if(isValid(locations,index,i)){
int t=locations[index];locations[index]=locations[i];locations[i]=t;
solve(res,locations,index+1);
t=locations[index];locations[index]=locations[i];locations[i]=t;
}
}
}
private boolean isValid(int[] locations,int index,int change){
for(int i=1;i> res,int[] locations){
List r=new ArrayList();
for(int i=1;i<=locations.length-1;i++){
StringBuilder builder=new StringBuilder();
for(int j=1;j<=locations.length-1;j++){
if(locations[i]==j){
builder.append("Q");
}else{
builder.append(".");
}
}
r.add(builder.toString());
}
res.add(r);
}
注:在统计结果数量时,由于Java本身都是按值传递参数的(对于对象传递的是地址值),因此我们不用用int类型统计结果数量,同时由于Integer是不可变的,因此也不能使用Integer。这里我采用Integer容器来统计数量,此外还可以利用AtomicInteger原子整型或自定义引用类型来进行统计,也可以在方法调用中返回结果数量。如有更好的方法忘指教,谢谢!!
public int totalNQueens(int n) {
ArrayList locations=new ArrayList();
Stack count=new Stack();
count.add(new Integer(0));
solve(locations,n,count);
return count.get(0);
}
private void solve(ArrayList locations,int n,Stack count){
if(n==locations.size()){
count.push(new Integer(count.pop()+1));
return;
}
for(int i=0;i locations,int location){
for(int i=0;i