[关闭]
@smilence 2016-08-25T22:11:31.000000Z 字数 4263 阅读 2014

第三部分:用“模式识别”来解决面试技术问题的方法学

算法面试指南


3.1 什么是“模式识别”?有什么用

3.2 “模式识别”的思维方法和举例

我们一起来模拟一下用“模式识别”和我们之前提到的原则来应对面试(而不只是解决这个题目)注意无论是讲解还是视频课程中都会尽量以英文术语为主,一方面是避免混淆,另外一方面通过这些希望大家养成程序中用英文规范命名的习惯

作业:e.g.4 Having N nodes, each with a value.Require each node running a function getSum() to get the sum of the values in the network.The values could vary with time. (网络中有N台机器,每台带有一个值,互相连接,假定他们都始终运行getSum()这样一个函数,返回值应该是网络中所有值的总和)

N nodes, each node consists of a couple fields and methods. These are:

int id; //every node has an ID. All of these IDs are sequential, and begin with 0. 
int val; //every node has a value  
int max; //max = N. Every node knows how many nodes are in the system.  
void send(int idTo, int payload);  
int recv(int idFrom);  

Write a single piece of code which runs on every node simultaneously, such that when it is finished running every node in the system knows the sum of the values of all the nodes in the system.

3.3 抽象数据类型与数据结构

ADT(抽象数据类型)与Data Structure(数据结构)的区别:
ADT代表的是有某种功能,就像是个interface(接口);而Data Structure是一种它的具体implementation。
e.g. Hashtable也可以用BST,只要实现lookup这种功能。用程序语言表示是两个concrete的class都implement了 ICanLookup 这个interface

Linked List 是 ADT还是Data Structure?
ADT 与具体实现以至于performance是无关的
List是ADT,无论是ArrayList还是LinkedList,都可以插入删除查找。
LinkedList插入删除很高效,但是有额外的overhead,根据index随机访问很低效。

说这些,用意在于思考:我为什么要选择这个Data Structure? 实际上首先是根据问题的特征选择ADT (a sequence of numbers),其次是根据performance的requirement来选择 (比如是一个数据流,并且需要插入删除)。
e.g. LRU缓存 - 需要插入删除的数据串,并且需要快速地检索

Stack/Queue - ADT 最简单的判定方法是他们有不同的implementation
Heap 堆栈 - Data Structure, Priority Queue 是 ADT
Queue 就是priority queue的一个特例

interface IQueue extends IPriorityQueue (where getPriority() returns getInsertedOrder());
class Heap implements IPriorityQueue;

JAVA的Stack是stack的一个实现,就像C++的PriorityQueue一样。这么命名的用意只是在于你不需要去关心内在的实现。

N nodes, each node consists of a couple fields and methods. These are:

int id; //every node has an ID. All of these IDs are sequential, and begin with 0. 
int val; //every node has a value  
int max; //max = N. Every node knows how many nodes are in the system.  
void send(int idTo, int payload);  
int recv(int idFrom);  

Write a single piece of code which runs on every node simultaneously, such that when it is finished running every node in the system knows the sum of the values of all the nodes in the system.

首先应该从问题的特征出发去分析:
每台机器上运行的代码都完全一致,但每台机器并不一定是对等的;
机器之间有互相连接的关系;
每台机器都同时发送和接收

1.机器之间是怎么样的连接关系,也就是怎么样的数据结构?
2.连接关系之间的方向性,也就是发送给谁,向谁接收?

解法:
a. 两两互相传递
b. 假定一台为SERVER ,负责发送,其他都接收总和的值
c. 时间复杂度是否可能比O(n)更好呢?能否从机器之间并行计算的角度出发,避免不平衡的计算 (load balance), 抽象到数据结构就是用具备D&C特性的tree,通过并行计算subproblem来更快的解决problem

Binary Tree 天生具有D&C的特性,能够很方便地掌握子树的情况,并在整个数据结构中传递全局信息。

  1. int getSum() { //as member function of the node
  2. int parent = ( id - 1)/2;
  3. int left = 2*id + 1;
  4. int right = 2*id + 2;
  5. // DFS
  6. int subsum = val;
  7. if( right < max ) subsum += recv(right);
  8. if( left < max ) subsum += recv(left);
  9. if(parent >= 0 ) send( parent, subsum);
  10. int sum = 0;
  11. if(parent >= 0) sum = recv( parent);
  12. else sum = subsum;
  13. send( left, sum);
  14. send(right, sum );
  15. return sum;
  16. }

这是一道模式难以解答的问题,但也并非没有规律。Divide and Conquer(分治法)加上 并行计算的概念。BST天生具有D&C(分治)属性,并且:利用BST维护的稳定性,BST的节点可以方便地记录其子树的信息,并在节点间传递全局信息,方便检索。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注