最近在看一本书,叫做《思考的乐趣》,第26节“我最爱的证明”,里面介绍了这样一则有趣的问题(文章链接在此):
设想一个平面上布满间距为1的横纵直线,形成由一个个1×1正方形组成的网格。任意给一个面积小于1个单位的图形,证明这个图形总能放在网格中而不包含任何一个格点。
初看这个论断,觉得似乎是正确的,但又不知从何下手。文中指出证明的思路很巧妙,让人感到数学的美妙。我的感触是,文中的证明大大地换了个角度,很有峰回路转的感觉。正在读这篇文章的你,不妨先思考一下,别急着往下看答案。
如果陷入了拼命去构造各种各样的图形类别,去思考不同类别图形的情况下,怎么去摆放这样的图形,使得图形不覆盖到格点,就如同陷入了泥沼,很难绕清楚路线了。思考问题的情况往往类似,如果一条路走不通,又觉得似乎并不复杂,不愿意轻易放弃,就很容易陷进去难以自拔。这样的问题思考情形并不特指常规意义上的算法题,而包含了各种各样的实际问题。
再来看看文中的解答:
我们可以这样考虑这个问题:把图形随意放在网格中,如何移动网格使每个格点都在图形外面。
现在我们把给定的图形随意放在网格中。然后沿着网格线把包含有图形的网格切成1×1的小格子,从网格中拿出来。把它们重叠起来(不旋转),再想像这些格子是透明的,而图形是不透明的。从上往下看这一叠格子,你看到的会是这个图形的各部分重叠地放在一个格子中,仿佛一个沾有污渍的方块。很显然这些污渍不会布满整个方块(图形面积小于一个格子的面积),方块上总有一块干净的地方。现在我们用一颗针从一个干净的地方刺下去,把这些重起来的格子刺穿。把这些格子放回原来的网格中,你看到的会是每一个有图形的方格内都有一个针眼,这些针眼都不在图形内。现在可以把原来的网格擦掉了,这几个针眼可以看作是新网格的格点。按针眼的位置重画新的网格,那么这个图形内决不会有新网格的格点,此时,结论也就证到了。
怎么样,是不是很巧妙?由相对固定网格,去摆放图形;改为相对固定图形,去摆放网格。问题居然一下子就清晰起来。我们都知道要换个角度去认识和思考问题,但是真正遇到问题的时候,又有多少人能够做到这一点呢?
再来看一道我很喜欢问的面试题:
假如说有这样一个SNS网站,每一个注册用户都有自己的主页。而网站中有这样一套积分系统,对于用户的各种各样的行为,都会引起用户积分的微小变化,例如,用户登陆一次+1分,用户加一个好友+2分,用户发表一篇评论+1分,用户评论包含不良内容-3分等等。现在,注册用户的个人主页上需要展示用户的个人信息(例如用户姓名),以及用户的积分,同时,还要展示用户的积分在网站所有用户(大约两千万用户)中精确的排名。现在为了简化问题,我们假设用户信息和积分信息全部存放在内存中。如果你要设计这样一个网站,你会怎样设计内存中存储这些信息的数据结构,以便在访问用户主页的时候迅速展示用户的积分和积分排名信息,同时,在用户积分发生上述变更的时候能够使排名得到快速更新?
我很喜欢问这样的问题是因为这样的问题在可以考察数据结构等等基础知识的同时,非常明确地考察了解决实际问题的能力。这样的问题远远比分析一个字符串、处理一个表达式这样的传统意义上的纯算法题有实际意义得多。在实际应用中,我通常会把它拆成几问,以降低难度,而且可以增加区分度。这道问题没有所谓的标准答案,有很多人都给出了非常漂亮的解答。我在此举一例而已,您也不妨先思考一下再往下阅读。
几乎所有的人都会首先想到使用HashMap来存储用户信息,key为用户id(uid),value为用户信息的对象,这样的好处是访问用户首页时,理论上获取用户信息的的时间复杂度是常数阶的,非常快。可是很多聪明的人也会忽然意识到,存储积分容易,但是排名信息的更新呢?如果排名信息作为value的一部分存储在这个HashMap里,当分数发生变更的时候,有那么多的用户,我需要遍历所有的value,取出积分来重新排序,这样的时间复杂度是很难接受的。
如果只是把思路限制在“根据用户id去取得排名”,就很难得到最优的解决方案,比较好的同学也只是想出使用树等等可以让时间复杂度为log(n)的设计。但是,如果我们换个角度思考问题,变成“根据用户排名去取得用户信息”,问题说不定就豁然开朗了。“排名”有一个天然的优势是一定是从1开始的连续正整数列表,它的长度就等于所有用户的数量。当我提示到这一句话的时候,有些本来没有头绪的同学也能够自己把问题解答下去了——这样的数据结构形式,非常适合使用数组来表达,根据下标去访问元素,是非常快的。于是设计一个数组Array,下标表示用户排名,值表示用户信息对象(例如用户名、描述等等):
1
|
Array[rank] = userInfo |
这样的设计还有什么好处?当用户积分发生变更的时候,请注意题中的说明,每次变更都是“微小变化”,对于这样一个偌大的数组而言,每次积分变更引起的用户排名的调整往往非常小,例如用户积分为29876分,增加了3分,变成了29879分,那么引起变化的只有从29876到29879积分的用户排名,换言之,只需要在数组中向上游或者下游简单地寻溯遍历几个元素而已;而且,对于这样的调整来说,不需要锁住整个数组,而只需要锁住其中小小的一个区段而已。
别急,问题还没有解决,现在的问题变成了,给定用户uid的时候,我怎样能够快速取得用户的排名(rank)呢?因为有了排名我才能从刚才的数组里面去取得用户信息啊。回过头来看一看,原本的HashMap不是可以派上用场吗?设计这样的HashMap,让key为uid,value为用户的排名信息(rank),每次在用户需要获取排名信息的时候,先根据uid在HashMap中取得rank,再根据rank在Array中取得用户信息:
1
|
HashMap<uid, rank> |
这样一来,rank变成了HashMap和Array的桥梁,在每次分数发生微小变更时要做的调整,以及每次根据uid来获取用户的积分和积分排名信息时要做的查询,全部都是常数阶的。这两个数据结构本身都很简单,但是在遇到实际问题的时候,将实际问题是用最合适的数学和工程模型来解决的能力,这本身应当是属于比传统意义上纯粹的算法问题更有考察价值的部分。
我还在《再谈大楼扔鸡蛋的问题》里面介绍了一个使用等差数列求和公式来解题的证明,其中的思路也是“换个角度思考问题”,把“给定大楼层总数情况下,思考最少要扔多少次鸡蛋来确定鸡蛋恰好破碎的临界层”,变成“给定扔鸡蛋的最多次数的情况下,思考最多可以在多少层高的大楼内确定鸡蛋破碎的临界层”。如果您感兴趣请移步。
也许我们都做过很多需要换个角度思考的题目,例如在物理中我们有时需要改变参考系,在数学中有时我们需要改变坐标系,但是要真正理解它却并不容易。前两天在解决一个并不复杂的几何问题的时候,一眼就看出问题可以通过解析几何的办法来解答,但是仅仅利用初等的三角形的性质,却觉得无从下手,最后费了好大劲才搞定。为什么一定要用那么强大的工具来解决简单的问题呢?“换个角度”的实质在于需要改变思考问题的切入点和方向,而当我们掌握了通用的解题思路以后,掌握了更强大的解决问题的技巧以后,为什么原本或开阔或自然的思路反而被压制了呢?
文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》
相关推荐
换个角度思考:很多人,会把一些问题看成应该用常规的方法去解决.有时候换个角度,或许有更加新奇的发现.而很多问题难题也会迎刃而解。换个角度看问题,有利于发现新的解题方法,有时可在毫无办法时找到希望。
1. 换个角度看问题:在遇到困难或挫折时,尝试从不同角度思考,可能会找到新的解决方案和机会。 2. 创新思维:1+1大于2的概念,意味着通过整合和创新,原有的资源可能产生更大的价值。 3. 自我发现与自我价值:每个...
在基于Excel VBA测绘数据处理的相关论文中,一般都涉及到了角度转换问题,但通过验证发现,有些因其算法缺陷,对个别输入值将不能得到正确结果,其原因是在算法中没有充分考虑到计算机运算的精度问题。基于此,作者通过...
最后,作者使用了一些比喻和生动的描述,试图让读者在没有数学公式的限制下,通过思考和想象来理解傅里叶变换。整个内容没有出现具体的数学公式,而是通过文字和简单的图示来帮助读者构建对傅里叶变换基本概念的直观...
《换个角度思考,非常深刻的案例》的PPT探讨了一个引人深思的管理哲学问题,其核心在于如何从不同视角看待生活中的事件,并通过积极的思维方式来改变可能的结果。在这个案例中,SINO LIFE INSURANCE YUEHONG提出了一...
除了度分秒与度之间的转换,还需要考虑角度与弧度之间的转换。在Excel中,可以直接使用 `RADIANS()` 和 `DEGREES()` 函数来实现这一转换: - **角度转弧度**:`D2=RADIANS(A2)` - **弧度转角度**:`E2=DEGREES(D2)`...
假设我们有一个变量`angle`存储了上述格式的角度值,首先需要将角度值分离成度、分和秒,然后转换成弧度。具体步骤如下: - 将总角度拆分为度、分和秒:`degrees = floor(angle);`,`minutes = floor((angle - ...
《换个角度看问题》这篇课文是广东省河源市八年级语文下册第二单元的一篇重要文章,旨在引导学生理解和掌握从不同角度分析问题的思维方式。在教学过程中,教师将通过一系列的教学流程来帮助学生深入理解课文内容,...
3. 过程与方法:通过角色扮演等互动方式,训练学生多角度思考问题的能力。 【教学重难点】 重点在于培养学生的多角度思考能力,难点是使学生真正理解他人的感受,学会理解、尊重、体谅和欣赏他人,并从内心深处应用...
### 换个角度看压力——培养积极心态的重要性 #### 引言 在快节奏的现代生活中,每个人都会面临各种各样的压力。如何有效地管理和调节这些压力成为了一个重要的议题。本文通过两个出租车司机的故事,探讨了从不同...
3. **错误处理**:考虑到用户输入,程序应包含适当的错误处理机制,如检查输入是否超出有效范围(角度在0到360度之间,弧度在-π到π之间)。 4. **结果显示**:转换后的结果应该清晰地显示在界面上,可能是文本框...
林本杰在演讲中提出了“换个角度做开发”的新颖观点,他以此为出发点,深入探讨了iPhone开发过程中遇到的各种选择和决策问题。在移动开发领域,尤其是在iOS平台上的应用开发中,开发者经常会面临技术选型、设计模式...
并行计算是计算机科学中的一个重要概念,旨在提升计算效率,通过同时执行多个计算任务来解决复杂问题。在历史发展中,从第一台计算机ENIAC的20个累加器开始,到晶体管和集成电路的引入,再到微处理器的诞生,如Intel...
### 换个角度看人生的哲学思考 #### 1. 积极乐观的生活态度 - **电影启示**:电影中的大白以其乐观和积极的态度感染了周围的人,帮助他们度过了难关。 - **职业素养提升**:在快节奏的工作环境中保持积极乐观的心态...
这个故事启示我们,面对挫折时,要有创新思维,换个角度思考问题,可能就会找到解决办法。 2. **换个角度看问题**: - 在第二篇文章中,学生无意间解出了一道连数学家都觉得困难的题目。这说明有时候当我们不知道...
1. 应对挫折时,换个角度思考问题,创新的解决方案可能就隐藏其中。 2. 勤奋、专注和毅力是实现目标的关键,即使缺乏天生的优势,也能创造出令人惊叹的成果。 3. 心态决定命运,我们要学会控制自己的情绪,以积极的...
故事中,老太婆(哭婆)因为总是担忧两个儿子的生计问题而终日哭泣,直到一个过路人提醒她换个角度思考问题,从而转变了她的消极心态,成为了笑婆。这个故事引申到工作中,暗示了我们对待工作和生活的态度决定了我们...
这两个论题已经被充分讨论,这里不准备再作讨论,而是换个角度思考一下大数据,事实上可能与大数据存储平台更相关一点。这些需求或者思考,或源自用户模糊的需求,或源自存储同行的交流讨论,还
这个名为"角度转换程序"的项目旨在提供一个便捷的工具,用于在度、分、秒、十进制角度以及弧度之间进行灵活转换。下面我们将详细探讨涉及的相关知识点。 1. **角度表示**: - **度数制**:最常见的角度表示方式,...
接下来,我将详细解读红外发射管的发射角度与强度相关问题。 首先,红外发射管的发射角度是指红外光辐射分布的发散范围。在红外发射管的发光强度分布图形中,2θ1/2(亦称为半功率角度)是指发光强度大于最大强度...