宽德资本一面面经(3.30)

通过同学介绍去面的。

自我介绍

C++

因为我不会C++,因此C++的问题我有点忘了,只能大概凭印象写下。

定义一个对象需要多少字节(忘了怎么描述)

虚函数可以在构造函数里使用吗(不会)

不可以。虚函数对应一个vtable,这大家都知道,可是这个vtable其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数。

static关键字

按照Java里面的static讲了。

this指针的问题(忘了,不会)

面试官觉得挺尴尬的,说开始问问算法吧,就换了问题。

链表判断有没有环

剑指offer原题,用快慢指针并判断是否相遇就可以了。

链表有环,判断入口位置

剑指offer原题,直接讲了个结论。让我证明,结果想了半天才好不容易证明出来。

链表图

假设链表头指针为C点,入口为B点,相遇点为A点,CB之间的距离为x,BA之间的距离为a,AB之间的距离为b,我们要求的是x的长度。

我们使用快慢指针,slow和fast,slow是每次走一步,fast是每次走两步,路程用S表示,速度用V表示,可得到:
Sslow           = Sfast
x + (a + c * m) = x + (a + c * n)   // c=a+b,即快慢指针分别走了m次环和n次环。

2 * Vslow           = Vfast // 由于时间是一样的,因此速度和路程可等效替换
2 * (x + a + c * m) = x + a + c * n
x + a               = c * (n - m)
x                   = c * (n - m - 1) + c - a
x                   = b

所以可以得到x的长度就是b的长度了。即当快慢指针相遇的时候,让其中一个指针回到C点处,然后同时每次走一步,当再次相遇的结点就是入口了。

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode fast, slow;
        if (pHead == null || (slow = pHead.next) == null || (fast = slow.next) == null) return null;
        while (slow != fast) {
            // 没有环就退出
            if (fast.next == null || fast.next.next == null) return null;
            fast = fast.next.next;
            slow = slow.next;
        }
        // 找到了环
        fast = pHead;
        while (slow != fast) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

两个无序数组求合并后的中位数

印象中在 Leetcode 有,但是当时想了想没思路,结果遇到了。

  1. 一开始我说先合并,然后两边排序,再找。(最蠢的做法)
  2. 然后再说用一个map存下来,map相当于计数器,从前往后遍历直到计数到中间的时候就可以找到中位数。然后想了想觉得还不如第一种做法优呢。
  3. 最后说了可以用快排的思想去做,但是分开两个数组比较麻烦,如果允许重新开一个数组存的话,那么是比较容易实现的。但是这个复杂度还是比较慢,最优是O(n),最慢是O(n^2)。

原来 Leetcode 是排序的情况:题目链接,复杂度可以到 O(log(n+m))。

希望有人能告诉我下最优的做法。。。

智力题(被提示了)

现在有无限根质量不均匀的绳子,烧完一根绳子需要一个小时,问要得到一个小时十五分钟最少需要多少根绳子。
一开始和面试官沟通了好久质量不均匀的定义,然后就不会做。
面试官提示可以从左端和右端同时烧可以得到半个小时。我才醒悟,原来有这种操作。

于是,半个小时可以由绳子的左右端同时烧得到,那么要得到十五分钟的话,就是用两根绳子:第一根从一端开始烧,第二根从两端同时烧,当第二根烧完的时候,在第一根的另一端也同时烧。得到十五分钟这个操作耗费了四十五分钟(第二根烧完的半个钟+第一根的十五分钟),那么还需要半个钟,就再用一根绳子左右同时烧。因此答案是三根

总结

C++完全不会,尬聊。证明题想了太久了,面试官肯定很不爽。智力题也是想了挺久。
凉凉。

你可能感兴趣的:(宽德资本一面面经(3.30))