Seeker的奇妙求职历险(雷火测开三面和腾讯视频后台一面)

智力题

高楼扔鸡蛋

100层楼和2个鸡蛋,求最少几次能够一定知道鸡蛋在哪一层扔下来会碎。

https://leetcode-cn.com/problems/super-egg-drop/
当楼层为100,鸡蛋为2的时候,最少需要14次。

天平称重

给你12个球和一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球,并知道是轻了还是重了。

答:先分成3堆4个,然后不会了。
https://www.cnblogs.com/yan456jie/p/5369362.html

4个人过桥

四个人晚上要过一个桥回家,
由于桥上的灯坏了,只能用四个人仅有的一个手电筒照明,手电筒只能坚持照明17分钟.
而且桥很窄,一次只能通过两个人,
四个人过桥的速度也不同,甲乙丙丁过桥需要的时间分别是1分钟.2分钟.5分钟.10分钟.
问:怎样能让4人全部照明通过

答:先让甲乙过桥,2分钟,然后甲回来1分钟,丙丁过桥10分钟,乙回来2分钟,甲乙过桥2分钟,10+2+2+2+1 = 17。

雷火算法题

最小公共子串

给定两个字符串s1和s2,求这两个字符串的所有最长公共子串(连续的)。

分析:最小公共子串问题,不求最大长度,而是求字符串。
其实最小公共子串问题没什么好说的,但是我一紧张连dp方程都写不出来了,最后想用暴力解决还出了BUG,我好菜啊。

//暴力匹配,晚点再更新dp的做法
public static void main(String[] args) {
    //Scanner in = new Scanner(System.in);
    //int a = in.nextInt();
    //System.out.println(a);
    //s1 s2
    List<String> r = getString("abccccabcd","abcdcccc");
    for(String s:r){
        System.out.println(s);
    }
}
//abcccc  abc  3  abc
//ArrayList<String>
public static ArrayList<String> getString(String s1,String s2){
    char[] char1 = s1.toCharArray();
    char[] char2 = s2.toCharArray();
    ArrayList<String> res = new ArrayList<>();
    res.add("");
    String tmp;
    for(int i=0;i<char1.length;i++){
        for(int j=0;j<char2.length;j++){
            if(char1[i] == char2[j]){
                tmp = find(char1,i,char2,j);
                if(tmp.length() > res.get(0).length()){
                    res.clear();
                    res.add(tmp);
                }else  if(tmp.length() == res.get(0).length())
                    res.add(tmp);
            }
        }
    }
    return res;
}
public static String find(char[] char1,int start1,char[] char2,int start2){
    StringBuilder sb = new StringBuilder();
    while(start1 < char1.length && start2<char2.length){
        if(char1[start1] == char2[start2]){
            sb.append(char1[start1]);
            start1++;
            start2++;
        }else{
            break;
        }
    }
    return sb.toString();
}
//dp版,没有对字符串去重
public static void main(String[] args) {
    List<String> list =  commonString("abcccccabcd","abcdcccc");
    for (String s:list){
        System.out.println(s);
    }
}
public static List<String> commonString(String s1,String s2){
    int n = s1.length();
    int m = s2.length();
    char[] char1 = s1.toCharArray();
    char[] char2 = s2.toCharArray();
    int[][] dp = new int[n+1][m+1];
    List<String> res = new ArrayList<>();
    res.add("");
    for(int i=1;i<dp.length;i++){
        for(int j=1;j<dp[0].length;j++){
            if(char1[i-1] == char2[j-1])
                dp[i][j] = dp[i-1][j-1]+1;
            else
                dp[i][j] = 0;
            if(dp[i][j] > res.get(0).length()){
                res.clear();;
                res.add(s1.substring(i-dp[i][j],i));
            }else if(dp[i][j] == res.get(0).length()){
                res.add(s1.substring(i-dp[i][j],i));
            }
        }
    }
    return res;
}

制高点

1.有一个二维数组,里面各值代表山坡高度(值均>1),要求你找到所有制高点。
2.所谓制高点:指可以从这个点往上下左右四个边界都能走出去。例如图中7、6以及第2行第3列的5,这三个点都是制高点。
3.移动规则:可以从一个点向上下左右四个方向走,只能走向不大于自己的值的位置。

matrix = [ [1, 3, 2, 3, 5],
[3, 4, 5, 6, 3],
[2, 7, 4, 3, 3],
[5, 2, 2, 3, 1] ]
输出 7 6 5

思路:从上下左右4条边进行深度优先遍历,然后把遍历到的点放入数组中,一共4个数组,然后取交集(面试官提示的思路)。
不过话说回来,4个数组求交集挺麻烦的吧,我感觉额外开一个二维数组,把边遍历到的次数保存下来比较好吧。

    static boolean[][] visited;
    public static void main(String[] args) {
//        Scanner scan = new Scanner(System.in);
//        int n = scan.nextInt();
//        int m = scan.nextInt();
//        int[][] matrix = new int[n][m];
//        for(int i=0;i<n;i++){
//            for(int j=0;j<m;j++){
//                int tmp = scan.nextInt();
//                matrix[i][j] = tmp;
//            }
//        }
        int n = 4,m = 5;
        int[][] matrix = new int[][]{
            {1,3,2,3,5},
            {3,4,5,6,3},
            {2,7,4,3,3},
            {5,2,2,3,1},
        };
        List<int[]> up = new ArrayList<>();
        List<int[]> down = new ArrayList<>();
        List<int[]> left = new ArrayList<>();
        List<int[]> right = new ArrayList<>();
        visited = new boolean[n][m];
        //最上面一行
        for(int i=0;i<m;i++){
            a1(matrix,0,i,up);
        }
        //right
        visited = new boolean[n][m];
        for(int i=0;i<n;i++){
            a1(matrix,i,m-1,right);
        }
        visited = new boolean[n][m];
        //left
        for(int i=0;i<n;i++){
            a1(matrix,i,0,left);
        }
        visited = new boolean[n][m];
        //down
        for(int i=0;i<n;i++){
            a1(matrix,n-1,i,down);
        }
        List<int[]> ans = new ArrayList<>();
        for(int[] tmp:up){
            if(find(left,tmp) && find(right,tmp) && find(down,tmp)){
                ans.add(tmp);
            }
        }
        for(int[] p:ans){
            System.out.println(matrix[p[0]][p[1]]);
        }
    }
    public static boolean find(List<int[]> list,int[] target){
        for(int[] i:list){
            if(i[0] == target[0] && i[1] == target[1])
                return true;
        }
        return false;
    }
    public static void a1(int[][] matrix,int i,int j,List<int[]> res){
        visited[i][j] = true;
        int[] p = new int[]{i,j};
        int tmp = matrix[i][j];
        res.add(p);
        if(i>0 && !visited[i-1][j] && matrix[i-1][j] >= tmp)
            a1(matrix,i-1,j,res);
        if(j>0 && !visited[i][j-1] && matrix[i][j-1] >= tmp)
            a1(matrix,i,j-1,res);
        if(i<matrix.length-1 && !visited[i+1][j] && matrix[i+1][j] >= tmp)
            a1(matrix,i+1,j,res);
        if(j<matrix[0].length-1 && !visited[i][j+1] && matrix[i][j+1] >= tmp)
            a1(matrix,i,j+1,res);
    }

腾讯算法题

微信跳-跳游戏

1、有100个格子,每个格子上有一 个蘑菇,蘑菇分为好蘑菇和毒蘑菇,好蘑菇增加体力值n,毒蘑菇消耗体力值n
2、人的初始体力值为m
3、跳的格子的距离与消耗的体力值成正比,正比关系是1:1
问题:输入一个人的初始体力值m和格子初始化序列list,求问:写一个函数, 判断该人是否能否跳到终点?如果不能,函数返回-1,如果可以,返回剩余的最大体力值。

分析:
这道题我在面试的时候想复杂了,想用dp或者是回溯法去解决。然后就被面试官吐槽说这道题有这么麻烦吗?一趟for循环就能解决了,让我下去再好好想想。
面试结束之后,我想了一想,其实这道题的解法非常简单,但是我在面试的时候可能过于紧张就完全没想到。

考虑一下毒蘑菇的情况,如果本来就无法跳到最后一格,吃了毒蘑菇导致体力下降之后就更加跳不到了。
再考虑一下好蘑菇的情况,跳格子是需要消耗体力的,一旦跳到好蘑菇的格子上之后,体力值是一定上升的(无论如何j-i的体力消耗是不可避免的)。
所以只要考虑只往好蘑菇的格子里跳,体力变化为(m-(j-i)+n),判断中间过程的体力是否会小于等于0即可。
这么简单的题,我面试时候怎么就没做出来呢

//假设一开始的时候在-1的位置,最后要到达100的位置
//具体的题目意思还是要面试的时候问问面试官
public static int tian(int m,int[] nums){
    int cur = m;
    int last = -1;
    for(int i=0;i<nums.length;i++){
        if(nums[i] > 0){
            cur+=nums[i]-(i-last);
            if(cur<=0)
                return -1;
            last = i;
        }
    }
    if(cur < nums.length-last)
        return -1;
    return cur-(nums.length-last);
}

这个故事告诉我们:面试的时候别紧张,先把题目看清楚,题目意思不明白就问问面试官。
说起来还不是面试官出完题就视频音频一关,搞得我很慌。
更新:已经灰了,果然是来随便面一下然后把我挂了,感谢腾讯给我的面试机会,过几年再来吧。

腾讯面试问题

  1. 扯了20多分钟项目
  2. TCP和UDP的区别,三次握手,SYN攻击,TIME_WAIT
  3. 进程和线程的区别,进程间通信
  4. 自己实现一个map
  5. 算法题

后记

腾讯我就知道我会挂,只是没想到还能有一次面试机会。相比较之前的面试,腾讯比较喜欢问网络相关的内容,一直以为自己准备的还不错结果TIME_WAIT在哪一端发生的都忘了,之后还是再好好看看。
雷火的测开面试居然有4轮,而且第4面的算法题还挺难的,我感觉字节也不过如此,我面的真的是测开?不过有一说一,最长公共子串的题目没有做出来不太应该,最后这种经典面试题还是需要多看看。
也不知道雷火面的怎么样,感觉面试官都是打个哈哈,先说你基础还不错,就是算法需要加强,然后反手把你挂了。
面试官的嘴,骗人的鬼,我太难了。


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值