几道趣味算法面试题

1.1 绳子计时问题

阿里曾面过这道题目,有若干根相同的不均匀的绳子,烧完一根绳子的时间是1小时,问如何计时1小时15分钟?

答案:能计时出15分钟就好办了,可以用两根绳子并排反向放置,同时从两端点着,烧到交接处弄灭,拿出烧剩下的其中任意一根,再从两端同时点着,烧完就是15分钟。

1.2 两座岛运输加锁问题。

A、B两人分别在两座岛上。B生病了,A有B所需要的药。C有一艘小船和一个可以上锁的箱子。可以让C在A和B之间运东西,但东西只能放在箱子里。只要箱子没被上锁,C都会偷走箱子里的东西,不管箱子里有什么。如果A和B各自有一把锁和只能开自己那把锁的钥匙,那么问:A如何把东西安全递交给B?

答案:A把药放进箱子,用自己的锁把箱子锁上。B拿到箱子后,再在箱子上加一把自己的锁。箱子运回A后,A取下自己的锁。箱子再运到B手中时,B取下自己的锁,获得药物。

1.3 马比赛问题

有25匹马,速度都不同,但每匹马的速度都是定值。现在只有5条赛道,无法计时,即每赛一场最多只能知道5匹马的相对快慢。问最少赛几场可以找出25匹马中速度最快的前3名?(百度2008年面试题)

答案:每匹马都至少要有一次参赛的机会,所以25匹马分成5组,一开始的这5场比赛是免不了的。接下来要找冠军也很容易,每一组的冠军在一起赛一场就行了(第6场)。最后就是要找第2和第3名。我们按照第6场比赛中得到的名次依次把它们在前5场比赛中所在的组命名为A、B、C、D、E。即:A组的冠军是第6场的第1名,B组的冠军是第6场的第2名……每一组的5匹马按照他们已经赛出的成绩从快到慢编号: A组:1,2,3,4,5 B组:1,2,3,4,5 C组:1,2,3,4,5 D组:1,2,3,4,5 E组:1,2,3,4,5 从现在所得到的信息,我们可以知道哪些马已经被排除在3名以外。只要已经能确定有3匹或3匹以上的马比这匹马快,那么它就已经被淘汰了,即:A组的2、3名;B组的1、2名,C组的第1名。取这5匹马进行第7场比赛,第7场比赛的前两名就是25匹马中的2、3名。故一共最少要赛7场。

1.4 高楼逃生问题

阿里面试题。如你被困在一幢200米高的大楼的楼顶。你手里有一根150米长的绳子和一把瑞士军刀。你所站的地方有一个铁钩子。往楼下看时,你发现大楼正中间,也就是100米高的位置上,有一个可以落脚的金属支架,上面还有另外一个钩子,问用现在的工具如何安全到达地面。

答案:把绳子割成50米和100米两段。把50米绳子的一端拴在楼顶的钩子上,另一端打一个小环。让100米长的绳子穿过这个环,再把它的两头系在一起形成一个绳圈。沿着绳子爬到落脚点,把100米长的绳子割断并收回来,然后把其中一端拴在钩子上,沿着绳子爬到地面。

1.5 对单链表排序,用代码实现,

腾讯面试题

typedef struct Node {
    int data;
    struct Node *pNext;
} NODE, *PNODE;
//链表的长度
int length_list(PNODE pHead) {
    PNODE p = pHead->pNext;
    int len = 0;
    while (NULL != p) {
        ++len;
        p = p->pNext;
    }
    return len;
}
//对链表排序
void sort_list(PNODE pHead) {
    int i, j, t;
    int len = length_list(pHead);
    PNODE p, q;
    for (i = 0, p = pHead->pNext; i < len - 1; ++i, p = p->pNext) {
        for (j = i + 1, q = p->pNext; j < len; ++j, q = q->pNext) {
            if (p->data > q->data) {
                t = p->data;
                p->data = q->data;
                q->data = t;
            }
        }
    }
}

复制

1.6 快速找到未知长度的单链表的中间节点

腾通讯面试题

普通解法:

遍历一遍单链表以确定单链表的长度L, 然后再次从头结点出发循环L/2次找到单链表的中间节点。 算法复杂度:O(L + L/2)=O(3L/2)。

利用快慢指针原理:

设置两个指针search, mid都指向单链表的头结点。其中search的移动速度是mid的两倍。但*search指向末尾节点的时候,mid正好在中间了。 代码实现(C语言)

typedef int ElemType;
typedef struct Node
{
    ElemType data; //数据域
    struct  Node *next; //指针域
} Node;
typedef struct Node *LinkList;
//快速找到未知长度单链表的中间节点 L:链表的头结点 *e返回的链表中间节点
bool GetMidNode(LinkList L, ElemType *e) {
    LinkList search, mid;
    mid = search = L;
    while (search->next != NULL) {
        if (search->next->next != NULL){
            search = search->next->next;
            mid = mid->next;
        } else {
            search = search->next;
        }
    }
    *e = mid->data;
    return true;
}

复制

你可能感兴趣的:(算法)