莉莉丝9.6服务端笔试

菜鸡的笔试记录

第一题

将链表节点便利,先头插再尾插

class Solution {
public:
    ListNode* formatList(ListNode* head) {
        ListNode* dummy = new ListNode(-1);

        ListNode* ptr = head;
        ListNode* flagtail = head;

        while (ptr != nullptr && ptr->next != nullptr) {
            ListNode* h = ptr;        // 待插入到头
            ListNode* t = ptr->next;  // 待插入到尾
            ListNode* nexthead = ptr->next->next;
            // 头插
            h->next = nullptr;
            h->next = dummy->next;
            dummy->next = h;
            // 尾插
            t->next = nullptr;
            t->next = flagtail->next;
            flagtail->next = t;

            flagtail = t;  // 更新链表尾部标志
            ptr = nexthead;
        }
        // 仅剩一个节点情况的处理
        if (ptr != nullptr) {
            ptr->next = dummy->next;
            dummy->next = ptr;
        }
        return dummy->next;
    }
};

测试用例

1 2 3 4 5  -->  5 3 1 2 4
1 2 3 4 5 6  --> 5 3 1 2 4 6

思路

需要记录每次插入操作的链表结尾的前一个节点,以供尾插时使用,用一个变量记录就好。暴力loop寻找尾结点会超时。

第二题

链表有重复元素,按照已有key的升序排序链表

struct ListNode {
    int val;
    struct ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        map<int, int> dict;

        ListNode* ptr = head;
        int num = 0;

        while (ptr != nullptr) {
            dict[ptr->val] += 1; // 计数
            ptr = ptr->next;
            ++num;
        }
        ListNode* dummy = new ListNode(-1);
        ListNode* p = dummy;

        while (num) {
            for (auto item : dict) {
                if (item.second > 0) {
                    p->next = new ListNode(item.first); // 重建链表
                    dict[item.first] = item.second - 1; // 修改剩余计数
                    p = p->next;
                    --num;
                }
            }
        }
        return dummy->next;
    }
};

测试用例

3 2 3 1 1 3  -->  1 2 3 1 3 3
2 1 2 1 3   --> 1 2 3 1 2

思路

统计链表中元素的出现次数,很适合使用字典存储,可以考虑使用 std::map kv结构,而且底层使用红黑树,按照iter++ 的方式输出就是有序序列,不用对字典排序了。按照元素的个数重建链表就 OK。

第三题()

看了一眼和LRU题型差不多,没时间写了

#莉莉丝笔试##笔经##莉莉丝游戏#
全部评论
约面试了吗
点赞 回复
分享
发布于 2021-09-13 11:24

相关推荐

头像
04-08 11:38
已编辑
门头沟学院 计算机类
快手二面:1.&nbsp;jdk1.8之后jvm的内存模型?1.8之后还有方法区吗?讲讲永久代、元空间是怎么回事?2.&nbsp;讲一下垃圾回收器?比较一下cms和g1以及各自的适用场景3.&nbsp;什么是oom?内存满了,怎么排查是代码哪里有问题?(我说pstack,他说不是栈满了,我说不会,没用过,面试官说没事可能有点偏有点偏业务应用)4.&nbsp;线程池有没有用过?核心线程和非核心线程区别是什么?核心线程数设置的考量因素有哪些?没有任务的时候核心线程和非核心线程是继续存在还是销毁?jdk有没有提供销毁核心线程节约资源的方法?我如果想要动态核心线程数而不需要重启服务怎么实现?(想了很久不知道。。)5.&nbsp;来个计网八股意思一下,讲一下tcp和udp的区别?慢启动是什么?6.&nbsp;mysql的索引数据结构是什么?聚簇索引和非聚簇索引的区别?数据库有哪些锁?select&nbsp;*&nbsp;from&nbsp;user&nbsp;where&nbsp;userid=5&nbsp;for&nbsp;update是什么锁?假如usreid是索引但是没有这个数据,锁的是什么?没有索引也没有5这个数据,锁的是什么?7.&nbsp;项目分布式锁为什么用redis不用别的?(一下不记得区别了,我说因为和java有redission集成,功能丰富并且使用方便。。)讲一下redis的集群结构?你们用的是什么?我说一主多从,他说流量大的时候扛不住,没有用分片吗?我说我知道分片slot,那个确实可以,不过我们数据量不大就没用。。跨服务的时候怎么保证多个数据库的数据一致性?然后还有针对项目业务场景的一些分布式问题。8.&nbsp;手撕:合并K个有序链表。我说顺序合并,面试官问时间复杂度是多少?能不能优化?优化后是多少?9.&nbsp;反问环节聊了15分钟,说快手80%流量都是他们组的,快手上下滑刷到的视频以及点赞评论收藏那些功能都是他们组,来这里之后做好卷的准备。我问对我有什么评价或者建议吗,面试官说虽然有些应用层次的深度还不够,不过其实还不错,应该问题不大,后续还有个老板的技术面,加油攒人品,求个三面4.8还愿:约三面了 #春招#
点赞 评论 收藏
转发
1 12 评论
分享
牛客网
牛客企业服务