继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

算法洗脑系列(8篇)——第四篇 枚举思想

所谓伊人_在水一方
关注TA
已关注
手记 273
粉丝 23
获赞 169

 

   今天分享一下枚举思想,这种思想也常是码畜,码奴常用的手段,经常遭到码农以上级别的鄙视,枚举思想可以说是在被逼无奈时最后的狂吼。

 

一: 思想

     有时我们解决某个问题时找不到一点规律,此时我们很迷茫,很痛苦,很蛋疼,突然我们灵光一现,发现候选答案的问题规模在百万之内,

此时我们就想到了从候选答案中逐一比较,一直找到正确解为止。

 

二: 条件

     前面也说了,枚举是我们在无奈之后的最后一击,那么使用枚举时我们应该尽量遵守下面的两个条件。

     ①   地球人都不能给我找出此问题的潜在规律。

     ②   候选答案的集合是一个计算机必须能够承受的。

 

三:举例

    下面是一个填写数字的模板,其中每个字都代表数字中的”0~9“,那么要求我们输入的数字能够满足此模板。

思路:首先拿到这个题,蛋还是比较疼的,因为找不到好的解题思路,仔细想想这属于查找类型的问题,常用的查找也就5种,能适合

        该问题的查找也就”顺序查找“和”二分查找“,然后仔细看看问题规模最多也就105=100000,其实根据“二分"的思想在这个问题

        中并不合适,最后只能用“顺序查找“了。

复制代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Meiju
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             int count = 0;
13 
14             //“算”字的取值范围
15             for (int i1 = 1; i1 < 10; i1++)
16             {
17                 //“法”字的取值范围
18                 for (int i2 = 0; i2 < 10; i2++)
19                 {
20                     //“洗”字的取值范围
21                     for (int i3 = 0; i3 < 10; i3++)
22                     {
23                         //"脑"字的取值范围
24                         for (int i4 = 0; i4 < 10; i4++)
25                         {
26                             //"题"字的取值范围
27                             for (int i5 = 1; i5 < 10; i5++)
28                             {
29                                 count++;
30 
31                                 //一个猜想值
32                                 var guess = (i1 * 10000 + i2 * 1000 + i3 * 100 + i4 * 10 + i5) * i1;
33 
34                                 //最终结果值
35                                 var result = i5 * 100000 + i5 * 10000 + i5 * 1000 + i5 * 100 + i5 * 10 + i5;
36 
37                                 if (guess == result)
38                                 {
39                                     Console.WriteLine("\n\n不简单啊,费了我  {0}次,才tmd的找出来\n\n", count);
40 
41                                     Console.WriteLine("\t{0}\t{1}\t{2}\t{3}\t{4}", i1, i2, i3, i4, i5);
42                                     Console.WriteLine("\n\n\tX\t\t\t\t{0}", i1);
43                                     Console.WriteLine("—————————————————————————————");
44                                     Console.WriteLine("\n{0}\t{1}\t{2}\t{3}\t{4}\t{5}", i5, i5, i5, i5, i5, i5);
45 
46                                     Console.Read();
47                                 }
48 
49                                 Console.WriteLine("第{0}搜索", count);
50 
51                             }
52                         }
53                     }
54                 }
55             }
56 
57             Console.Read();
58         }
59     }
60 }

复制代码

 

最后我们还是解决了问题,发现其中的时间复杂度达到了O(n5),这个复杂度理论上是让人不能接收的,还好我们的n在10以内,

n的每一次的自增对cpu来说都是莫大的伤害。

 

__________________________________________________________________________________________________

 

感谢一楼同学的提醒,你的眼睛很犀利,将O(n5)降低到O(n2),这是非常不错的,为你鼓掌一下。

现将你的想法用code实现一下。

复制代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace ConsoleApplication1
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             //商
13             int[] resultArr = { 111111, 222222, 333333, 444444, 555555, 666666, 777777, 888888, 999999 };
14 
15             //除数
16             int[] numArr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
17 
18             int count = 0;
19 
20             for (int i = 0; i < resultArr.Count(); i++)
21             {
22                 for (int j = 0; j < numArr.Count(); j++)
23                 {
24                     count++;
25 
26                     var result = resultArr[i].ToString();
27 
28                     var num = numArr[j].ToString();
29 
30                     var origin = (resultArr[i] / numArr[j]).ToString();
31 
32                     if (origin.LastOrDefault() == result.FirstOrDefault()
33                         && origin.FirstOrDefault() == num.FirstOrDefault()
34                         && result.Length - 1 == origin.Length)
35                     {
36                         Console.WriteLine("\n\n费了{0} 次,tmd找出来了", count);
37                         Console.WriteLine("\n\n感谢一楼同学的回答。现在的时间复杂度已经降低到O(n2),相比之前方案已经是秒杀级别\n");
38 
39                         Console.WriteLine("\t{0}\t{1}\t{2}\t{3}\t{4}", origin.ElementAt(0), origin.ElementAt(1), origin.ElementAt(2), origin.ElementAt(3), origin.ElementAt(4));
40                         Console.WriteLine("\n\n\tX\t\t\t\t{0}", num);
41                         Console.WriteLine("—————————————————————————————");
42                         Console.WriteLine("\n{0}\t{1}\t{2}\t{3}\t{4}\t{5}", result.ElementAt(0), result.ElementAt(0), result.ElementAt(0), result.ElementAt(0), result.ElementAt(0), result.ElementAt(0));
43 
44                         Console.Read();
45                     }
46                     Console.WriteLine("第{0}搜索", count);
47                 }
48             }
49             Console.WriteLine("无解");
50             Console.Read();
51         }
52     }
53 }

复制代码

 

 

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP