递归详解(三)

先来看一个题目:

今有7对数字:两个1,两个2,两个3,...两个7,把它们排成一行。 要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:
17126425374635
当然,如果把它倒过来,也是符合要求的。
请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。
注意:只填写这个14位的整数,不能填写任何多余的内容,比如说明注释等。

先说一下自己的解法:

 1 import java.util.LinkedList;
 2 import java.util.List;
 3 import java.util.Random;
 4
 5 public class Test {
 6     int m;
 7     int n;
 8     int first;
 9     int last;
10     int t;
11     String s = "74";
12     String sTemp = "";
13     int a[]={1,2,3,4,5,6,7};
14     Random random = new Random();
15     List ListA = new LinkedList();
16     public static void main(String[] args) {
17         Test example = new Test();
18         example.test();
19     }
20
21     public void test()  {
22
23         while(true)
24         {
25             ListA.add(1);
26             ListA.add(2);
27             ListA.add(3);
28             ListA.add(5);
29             ListA.add(6);
30             ListA.add(1);
31             ListA.add(2);
32             ListA.add(3);
33             ListA.add(5);
34             ListA.add(6);
35         //////////////////////////////////////////////////
36             for(int i=10;i>6;i--) {
37                 m=randomCreate(1,i);
38                 s=s+((ListA.get(m-1)).toString());
39                 ListA.remove(m-1);
40             }
41             s=s+"4";
42             m=randomCreate(1,6);
43             s=s+((ListA.get(m-1)).toString());
44             ListA.remove(m-1);
45             s=s+"7";
46             for(int i=5;i>0;i--) {
47                 m=randomCreate(1,i);
48                 s=s+((ListA.get(m-1)).toString());
49                 ListA.remove(m-1);
50             }
51         ///////////////////////////////////////////////////
52 //            上面一段代码随机出来一个74****4*7*****的序列
53 //            System.out.println(s);
54         /////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\
55             if(s.length() == 14) {
56                 for(int x=1;x<=7;x++) {
57                     sTemp = Integer.toString(a[x-1]);
58                     first = s.indexOf(sTemp);
59                     last = s.lastIndexOf(sTemp);
60                     t= last - first;
61                     if(t == (x+1)) {
62                         if(x==7) {
63                             System.out.println(s);
64                             break;
65                         }
66                         else {
67                             continue;
68                         }
69
70                     }
71                     else {
72                         break;
73                     }
74                 }
75             }
76             //判读序列是否符合要求
77            /////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\
78                 s = "74";
79                 ListA.clear();
80                 System.gc();
81     }
82 }
83     ////产生min到max之间的随机整数,包含min和max
84     public int randomCreate(int min,int max) {
85      int temp = random.nextInt(max)%(max-min+1) + min;
86     // System.out.println(temp);
87      return temp;
88  }
89 }

因为采用随机数的写法,时间不是很固定,一般入门i3处理器就在5,6分钟。结果:74151643752362

另外代码中有一点需要注意,s如果采用StringBuffer类型,拼接字符串采用apend(),会提示heap空间不足。感觉和书上讲的有出入。
如果不限定开头呢,编程找出所有结果。如果还按上面这种思路,14位数啥时候能随机上,想想中头彩的概率吧。如果采用穷举法呢,不好意思,1个小时也出不了结果。全部排列数为14!,大概就是8700亿种可能。经过实验,穷举法时间上能够接受的数量级在10!也就是300多万次。

后来,找到了大牛的代码,瞬间找出所有可能。而且代码很只有短短26行。佩服,还有谁!

 1 class C {
 2     static void findSo(int[] a, int n) {
 3         for (int i = 0; i < 14; i++) {
 4             if (i + n + 1 < 14 && a[i] == 0 && a[i + n + 1] == 0) {
 5                 a[i] = n;
 6                 a[i + n + 1] = n;
 7
 8                 if (n == 7) {
 9                     for (int j = 0; j < 14; j++) {
10                         System.out.print(a[j]);
11                     }
12                     System.out.print("\n");
13                 } else {
14                     findSo(a, n + 1);
15                 }
16                 a[i] = 0;
17                 a[i + n + 1] = 0;
18             }
19         }
20     }
21
22     public static void main(String[] args) {
23         int[] a = new int[14];
24         findSo(a, 1);
25     }
26 }
 1 17125623475364
 2 17126425374635
 3 16172452634753
 4 15167245236473
 5 14156742352637
 6 14167345236275
 7 16135743625427
 8 15173465324726
 9 15163745326427
10 15146735423627
11 51716254237643
12 41716425327635
13 41617435263275
14 71316435724625
15 71416354732652
16 61517346532472
17 46171452632753
18 73161345726425
19 46171435623725
20 56171354632742
21 74151643752362
22 57141653472362
23 36713145627425
24 57416154372632
25 26721514637543
26 45671415362732
27 23726351417654
28 34573641512762
29 23627345161475
30 52472654131763
31 26327435614175
32 26325734615147
33 24723645317165
34 52732653417164
35 52462754316137
36 35723625417164
37 27423564371516
38 25623745361417
39 52642753461317
40 57236253471614
41 53672352461714
42 34673245261715
43 72632453764151
44 72462354736151
45 62742356437151
46 72452634753161
47 57263254376141
48 73625324765141
49 37463254276151
50 35743625427161
51 53647352462171
52 46357432652171

该如何理解代码里的递归呢?

时间: 2024-10-13 10:18:50

递归详解(三)的相关文章

spark2.x由浅入深深到底系列六之RDD java api详解三

学习任何spark知识点之前请先正确理解spark,可以参考:正确理解spark 本文详细介绍了spark key-value类型的rdd java api 一.key-value类型的RDD的创建方式 1.sparkContext.parallelizePairs JavaPairRDD<String, Integer> javaPairRDD =         sc.parallelizePairs(Arrays.asList(new Tuple2("test", 3

php学习之道:WSDL详解(三)

通过声明方式定义绑定(binding)属性 如果你在服务中采用SOAP binding,你可以使用JAX-WS来指定一定数量的属性binding.这些属性指定对应你在WSDL中指定的属性.某些设置,比如参数类型,可以约束你实现的方法,这些设置也影响声明的效用. @SOAPBinding声明,定义在javax.jws.soap.SOAPBinding接口中.它提供发布时的SOAP Binding细节.如果@SOAPBinding没有被指定,则用缺省的doc/literal SOAPBinding.

UINavigationController详解三(转)ToolBar

原文出自:http://blog.csdn.net/totogo2010/article/details/7682641,特别感谢. 1.显示Toolbar  在RootViewController.m的- (void)viewDidLoad方法中添加代码,这样Toobar就显示出来了. [cpp] view plaincopy [self.navigationController  setToolbarHidden:NO animated:YES]; 2.在ToolBar上添加UIBarBut

logback -- 配置详解 -- 三 -- &lt;encoder&gt;

附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appender> logback -- 配置详解 -- 三 -- <encoder> logback -- 配置详解 -- 四 -- <filter> -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

Android基础入门教程——8.3.6 Paint API之—— Xfermode与PorterDuff详解(三)

Android基础入门教程--8.3.6 Paint API之-- Xfermode与PorterDuff详解(三) 标签(空格分隔): Android基础入门教程 本节引言: 上一节,我们学习了Xfermode中的三儿子:PorterDuffXfermode构造方法中的为一个参数: PorterDuff.Mode,我们在观看了16种图片混排模式后,又自己写代码来验证了一下文档中 18种不同的混排模式,18种是新增了ADD和OVERLAY两种模式!当然,仅仅验证知道是不够的, 本节我们来写个例子

LinearLayout详解三:LayoutInflater创建View过程分析

项目人力资源管理主要有以下几个过程: 编制人力资源管理计划 组建项目团队 建设项目团队 项目团队管理 编制人力资源管理计划 根据什么来编? 直观点就是你要干什么事?干这些事有哪些制约? 这个说起来好像和没说一样,但就我自己做的一些项目来说,有以下困难: 1> 项目前期需求是不具体不明确的 这样直接导致你做项目计划时WBS也是不明确的,进而你细化不了活动,自然你也没法 明确活动需要什么样的人. 这个时候怎么办? 就我个人而言,有2种员工很喜欢: 1> 数学思维强的, 注意不是会做高数题,是指给你

WebSocket安卓客户端实现详解(三)–服务端主动通知

WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 WebSocket安卓客户端实现详解(二)–客户端发送请求 终于是最后一篇啦,有点激动\ ( ≧▽≦ ) /啦啦啦, 服务端主动通知 热身完毕,我们先回顾下第一篇中讲到的服务端主动通知的流程 根据notify中事件类型找到对应的处理类,处理对应逻辑. 然后用eventbus通知对应的ui界面更新. 如果

Spring4.0MVC学习资料,ApplicationContext中的方法详解(三)

做为java开源的一部分,spring框架一直排在老大的位置.Spring4.0 是 Spring 推出的一个重大版本升级,进一步加强了 Spring 作为 Java 领域第一开源平台的地位.Spring4.0 引入了众多 Java 开发者期盼的新特性,如泛型依赖注入.SpEL.校验及格式化框架.Rest风格的 WEB 编程模型等.这些新功能实用性强.易用性高,可大幅降低 JavaEE 开发的难度,同时有效提升应用开发的优雅性.为了方便开发,Spring的ApplicationContext类,

View绘制详解(三),扒一扒View的测量过程

所有东西都是难者不会,会者不难,Android开发中有很多小伙伴觉得自定义View和事件分发或者Binder机制等是难点,其实不然,如果静下心来花点时间把这几个技术点都研究一遍,你会发现其实这些东西都很简单.OK,废话不多说,今天我们就来看看View的测量.View的测量纷繁复杂,不过如果能够做到提纲挈领,其实也不难.那么今天,我们就来扒一扒View的测量.本文主要涉及如下知识点: 1.View的测量 2.在父容器中对View进行测量 3.LinearLayout测量举例 4.最根上容器测量 如