java 打印数组的所有组合_Java实现:按要求打印数组的排列情况

问题描述:针对1、2、2、3、4、5 这6个数字,写一个函数,打印出所有不同的排列,例如512234、215432等,要求“4”不能在第三位,“3”与“5”不能相连。

打印数组的排列组合方式最简单的方法就是递归,但本题有两个难点:第一,数字中存在重复数字;第二,明确规定了某些位的特性。采用常规的求解方法似乎不能完全适用了。

换一种思维,把求解这6个数字的排列组合转换为大家熟悉的图的遍历问题,解答起来就容易多了,可以把1、2、2、3、4、5 这6个点看作图的6个结点,对6个结点两两相连可以组成一个无向连通图,这6个数字对应的全排列等价于从这个图中各个结点出发深度遍历这个图所有可能路径所组成的数字集合,例如,从结点1出发的所有遍历路径组成了以1开头的所有数字的组合。由于“3”与“5”不能相连,因此在构造图时使图中3和5对应的结点不连通就可以满足这个条件。对应“4”不能在第三位,可以在遍历结束后判断是否满足这个条件。

具体步骤如下:

(1)、用1、2、2、3、4、5 这6个数字作为6个结点,构造一个无向连通图。除了“3”与“5”不连通外,其它所有结点都两两相连。

(2)、分别从这6个结点出发对图做深度优先遍历。每次遍历完所有结点,把遍历的路径对于数字的组合记录下来,若这个数字的第三位不是“4”,则把这个数字存放到集合Set中(由于这6个树中有重复的数,因此最终的组合肯定也会有重复的。由于集合Set的特点为集合中的元素是唯一的,不能有重复的元素,因此通过把组合的结果放到Set中可以过滤掉重复的组合。)

(3)遍历Set集合,打印出集合中的所有结果,这些结果就是本问题的答案。

实现代码如下:

import java.util.HashSet;

import java.util.Iterator;

import java.util.Set;

public class GetAllCombination {

public static void main(String[] args) {

Solution5 ss=new Solution5();

Set set=ss.getAllCombination();

Iterator it=set.iterator();

while(it.hasNext()){

String string=(String)it.next();

System.out.println(string);

}

}

}

class Solution5{

private int[] numbers=new int[]{1,2,2,3,4,5};

private int n=numbers.length;

//用来标记图中结点是否被标记过

private boolean[] visited=new boolean[n];

//图的二维数组表示

private int[][] graph=new int[n][n];

//数字的组合

private String combination="";

public Set getAllCombination(){

//构造图

buildGraph();

//用来存放所有集合

Set set=new HashSet();

//分别从不同的结点出发深度遍历图

for(int i=0;i

this.depthFirstSearch(i,set);

}

return set;

}

private void buildGraph(){

for(int i=0;i

for(int j=0;j

if(i==j){

graph[i][j]=0;

}else{

graph[i][j]=1;

}

}

}

//确保在遍历3与5是不可达的

graph[3][5]=0;

graph[5][3]=0;

}

//对树从结点start位置开始进行深度遍历

private void depthFirstSearch(int start,Set set){

visited[start]=true;

combination=combination+numbers[start];

if(combination.length()==n){

//4不出现在第三个位置

if(combination.indexOf("4")!=2){

set.add(combination);

}

}

for(int j=0;j

if(graph[start][j]==1 && visited[j]==false){//表示start结点与j结点有连线,且没被访问过

depthFirstSearch(j, set);

}

}

combination=combination.substring(0,combination.length()-1);

visited[start]=false;

}

}

运行结果为:

312254

321524

325412

212543

125234

152324

123245

123254

251423

322145

431225

523241

312245

421325

212345

325421

315242

232145

125243

132524

341225

432251

322154

232154

132254

142325

431252

345221

413225

522134

451322

215243

512324

512423

213245

232451

321254

345212

231452

341252

512432

243152

213254

342251

321245

243215

223415

241523

342512

123425

342215

152423

425231

251324

432215

245123

422513

225143

243125

342521

252314

322415

422315

342125

432512

215234

245132

322514

225134

221345

345122

231425

152342

225431

152243

321542

412523

521234

123452

251342

521324

432521

242513

322541

342152

431522

521342

152234

432125

521243

152432

543122

225413

223451

243251

251432

125432

122345

122543

543221

425123

252341

143252

252413

512243

252143

245213

451232

542213

132452

325241

513242

125423

231245

521423

245231

542231

421523

543212

425132

321425

231542

521432

412325

452231

522413

231254

522314

425213

215432

145223

252431

143225

223145

145232

322451

232514

423251

541232

312452

321452

215423

252134

512234

223154

451223

231524

541223

522431

213452

325142

542321

241325

512342

423215

542312

542123

423125

522341

523124

413252

312425

522143

542132

452213

312524

132425

452312

312542

142523

325124

452123

251243

432152

513224

452132

232415

415223

213425

452321

523421

132245

523142

315422

541322

523214

341522

242315

221543

232541

325214

251234

132542

423152

415232

315224

523412

513422

---------------------

作者:pengzhisen123

来源:CSDN

原文:https://blog.csdn.net/pengzhisen123/article/details/79573729

版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值