2018/9/9 字节跳动笔试 ac三道(附思路)

好多都是 Leetcode 原题, 或者改编的。

1. 最大不重复子串

思路:

用一个 map used_char 保存所有字符出现的最后一次位置。

max_length 记录最大不重复子串的长度

begin 记录每一个不重复子串的起始位置

对字符串的字符进行一次遍历

  1. 如果这个字符之前出现过,并且当前不重复子串的起始位置小于等于其位置:

    更新 begin

  2. 否则

    更新 max_length

def get_max_substring(s):
    begin = 0
    max_length = 0
    used_char = {}

    for i in range(len(s)):
        s_i = s[i]
        if s_i in used_char and begin <= used_char[s_i]:
            begin = used_char[s_i] + 1
        else:
            max_length = max(max_length, i - begin + 1)

        used_char[s_i] = i

    return max_length

2. 所有看做一个整体的部门(寻找孤岛)

只过了 80, 应该是用例的问题

思路:

result = 0 保存结果

dfs 函数深度遍历,把所有相邻的 1 设为 0

遍历一遍二维数组,如果值为1, 用 dfs 函数把所有相邻的 1 设为 0

def get_single_department(array, M):
    def dfs(array, i, j):
        # 把 array[i][j]旁边的所有1设为0
        if i < 0 or j < 0 or i >= M or j >= M or array[i][j] != 1:
            return
        array[i][j] = 0
        dfs(array, i + 1, j)
        dfs(array, i - 1, j)
        dfs(array, i, j + 1)
        dfs(array, i, j - 1)

    if not array:
        return 0
    result = 0
    for i in range(M):
        for j in range(M):
            if array[i][j] == 1:
                dfs(array, i, j)
                result += 1

    return result

有效ip

没 ac 就不放代码了

讲下思路:

ip 分为四段,无非就是把每一段找出来。不符合要求,回溯。

合法 UTF-8

前面用例错了导致我想很久。。后来时间不够按照自己的思路写了写 a了40 md

抖音红人

按照自己的暴力思路写了下,本来以为会超时,结果ac了。

用两个 map: fensi_map 和 follower_map (不知道粉丝英语怎么拼,索性就用汉语拼音了,蛤蛤)

follower_map 存储一个人的所有关注者

fensi_map 存储 一个人的所有粉丝

数据结构是 int -> set ,因为 set 查找元素是否存在的复杂度为1

初始化

  1. 初始化 follower_map ,遍历一下输入
  2. 把自己添加到关注的人的粉丝列表中

设置一个 flag 表示搜索是否停止,然后进入下面的循环:

flag = False

对每一个人:

对他关注的每一个人:

对他的所有粉丝:

如果他的粉丝不在他关注的人的粉丝列表中(好绕):

加进去

flag 设为 True 表示有新的更新

停止条件就是 flag 为 False

大概思路就是这样,不过我觉得用图论的知识可能会简单一点,不过不太会=-=

def get_all_people_number(array, N, M):
    fensi_map = defaultdict(set)  # 一个人的所有粉丝
    follower_map = defaultdict(set)  # 一个人关注的所有人

    for i in range(0, 2 * M, 2):
        follower_map[array[i] - 1].add(array[i + 1] - 1)

    for i in range(N):
        for j in follower_map[i]:
            if i not in fensi_map[j]:
                fensi_map[j].add(i)
    flag = True
    while flag:
        flag = False
        for i in range(N):
            for j in follower_map[i]:
                for fensi in fensi_map[i]:
                    if fensi not in fensi_map[j]:
                        fensi_map[j].add(fensi)
                        flag = True

    for i in range(N):
        fensi_map[i].add(i)
    result = 0
    for key in fensi_map.keys():
        if len(fensi_map[key]) == N:
            result += 1
    return result


#字节跳动##笔试题目##题解#
全部评论
还有螺柱说的求孤岛的,我刚开始用了DFS,没加DP,过了80,提示的错误也是数组越界,然后我猜可能是栈溢出,在本地输入了一个1000X1000全是1的数组,结果溢出了,然而时间所剩无几,没有将DFS改为循环,完了写了循环的方式,可以解决1000X1000全是1的情况,但是不知道能不能真的AC,也有人说是第二个的此时用例还是初始化有问题,那可能是吧,下边是我循环的代码 import java.util.ArrayDeque; import java.util.Scanner; /* 4 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 */ public class Main {     public static void main(String[] args) {         Scanner in = new Scanner(System.in);         String line = in.nextLine();         int N = Integer.parseInt(line);         String[] split = null;         boolean stand[][] = new boolean[N][N];         boolean flag[][] = new boolean[N][N];         for (int i = 0; i < N; i++) {             line = in.nextLine();             split = line.split(" ");             for (int j = 0; j < N; j++) {                 if (split[j].equals("1"))                     stand[i][j] = true;             }         }         System.out.println(findTeam(N, stand));     }     public static int findTeam(int N, boolean stand[][]) {         boolean flag[][] = new boolean[N][N];         ArrayDeque<Integer[]> deque = new ArrayDeque<>();         int ret = 0;         for (int i = 0; i < N; i++) {             for (int j = 0; j < N; j++) {                 if (stand[i][j] && !flag[i][j]) {                     deque.offer(new Integer[] { i, j });                     flag[i][j] = true;                     while (!deque.isEmpty()) {                         Integer[] site = deque.poll();                         int m = site[0];                         int n = site[1];                         if (m > 0 && stand[m - 1][n] && !flag[m - 1][n]) {                             deque.offer(new Integer[] { m - 1, n });                             flag[m - 1][n] = true;                         }                         if (n > 0 && stand[m][n - 1] && !flag[m][n - 1]) {                             deque.offer(new Integer[] { m, n - 1 });                             flag[m][n - 1] = true;                         }                         if (n < N - 1 && stand[m][n + 1] && !flag[m][n + 1]) {                             deque.offer(new Integer[] { m, n + 1 });                             flag[m][n + 1] = true;                         }                         if (m < N - 1 && stand[m + 1][n] && !flag[m + 1][n]) {                             deque.offer(new Integer[] { m + 1, n });                             flag[m + 1][n] = true;                         }                     }                     ret++;                 }             }         }         return ret;     } }
点赞 回复 分享
发布于 2018-09-09 13:03
第二题,把每个部门看成一个子树,就是一个合并子树问题。https://blog.csdn.net/anlian523/article/details/82557981 第五题,邻接表,分别对每个节点深度遍历,深度遍历的次数就是粉丝数量。 https://blog.csdn.net/anlian523/article/details/82557468
点赞 回复 分享
发布于 2018-09-09 16:16
fans
点赞 回复 分享
发布于 2018-09-09 12:48
UTF8这个其实不改也没有问题,可以将给出的数组看成是多个字符的编码,然后判断是否合法,一下我的代码,改之前和之后都可以AC import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String line = in.nextLine(); int N = Integer.parseInt(line); int code[] = new int[N]; String[] split = in.nextLine().split(" "); for(int i = 0; i < N; i++) { code[i] = (Integer.parseInt(split[i]) & 255); } int index = 0; int ret = 1; while(index != N && ret == 1) { if(code[index] <= 127) { index++; continue; } if(code[index] >= 192 && code[index] <= 223) { if(!(code[index + 1] >= 128 && code[index + 1] <= 191)) ret = 0; index += 2; continue; } if(code[index] >= 224 && code[index] <= 239) { if(!(code[index + 1] >= 128 && code[index + 1] <= 191 && code[index + 2] >= 128 && code[index + 2] <= 191)) ret = 0; index += 3; continue; } if(code[index] >= 240 && code[index] <= 247) { if(!(code[index + 1] >= 128 && code[index + 1] <= 191 && code[index + 2] >= 128 && code[index + 2] <= 191 && code[index + 3] >= 128 && code[index + 3] <= 191)) ret = 0; index += 4; continue; } ret = 0; } System.out.println(ret); } }
点赞 回复 分享
发布于 2018-09-09 12:52
有效ip那道可以想象字符之间存在一个空格,这样一来实际上就是空格里面选4个放点的排列组合问题。
点赞 回复 分享
发布于 2018-09-09 12:53
最后一道没考虑被关注列表中有自己,血崩……
点赞 回复 分享
发布于 2018-09-09 12:54
IP那个LeetCode上做过,我记得最出乎意料的一点是以0开头的,只能是0,其他判断都还比较简单,DFS+DP很容易解决,代码是我LeetCode上的解决办法,问题略有不同,原问题返回所有IP,这里我size了一下 import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Stack; public class Main {     public static void main(String[] args) {         Scanner in = new Scanner(System.in);         String line = in.nextLine();         System.out.println(restoreIpAddresses(line).size());     }          public static List<String> restoreIpAddresses(String s) {         List<String> ret = new ArrayList<>();         if (s == null || s.length() < 4 || s.length() > 32)             return ret;         findIP(s, 0, 3, new Stack<>(), ret);         return ret;     }          public static void findIP(String s, int start, int part, Stack<String> stack, List<String> ret) {         if (part == -1) {             ret.add(toIP(stack));             return;         }         for (int i = start + 1, count = 0; count < 3 && i <= s.length(); i++, count++) {             if (s.length() - i >= part && s.length() - i <= 3 * part && Integer.parseInt(s.substring(start, i)) < 256) {                 stack.push(s.substring(start, i));                 findIP(s, i, part - 1, stack, ret);                 stack.pop();             }             if (s.charAt(start) == '0')                 break;         }     }     public static String toIP(Stack<String> stack) {         StringBuilder ret = new StringBuilder();         for (String s : stack) {             ret.append(s).append(".");         }         return ret.deleteCharAt(ret.length() - 1).toString();     } }
点赞 回复 分享
发布于 2018-09-09 12:56
你收到面试通知了吗
点赞 回复 分享
发布于 2018-09-14 14:21

相关推荐

01-07 16:20
已编辑
门头沟学院 软件测试
点赞 评论 收藏
分享
评论
4
33
分享

创作者周榜

更多
牛客网
牛客企业服务