LeetCode 1789, 6, 138

目录

1789. 员工的直属部门

题目链接

1789. 员工的直属部门

  • Employee的字段为employee_iddepartment_idprimary_flag

要求

  • 请编写解决方案,查出员工所属的直属部门。
  • 返回结果 没有顺序要求

知识点

  1. count():统计个数的函数。
  2. group by:根据字段分组。

思路

直属部门的定义是 primary_flagY 或者 他只属于一个部门,知道这个定义后,思路就很明显了:先获取只属于一个部门的员工的id employee_id,然后将这些数据作为子表,放到限制条件中,限制条件还有一个 primary_flag = 'Y',它们的关系是

代码

sql 复制代码
select
    employee_id,
    department_id
from
    Employee
where
    primary_flag = 'Y'
or
    employee_id
in
    (
        select
            employee_id
        from
            Employee
        group by
            employee_id
        having
            count(*) = 1
    )

6. Z 字形变换

题目链接

6. Z 字形变换

标签

字符串

思路

做这道题时是我想起了高中物理中的简谐运动 ,可以将其简单理解为正弦函数 y = s i n x y=sinx y=sinx,横轴为时间轴,竖轴为位移轴,只看竖轴的话,那么就是一个质点随着时间流逝在做上下往复的运动,当它到极限(波峰或波谷)时,它就得掉头(调转向上或向下的方向),如下图所示:

讲完这个东西后,理解本题的解法就更容易了。本题可以将原字符串当作这个做简谐运动的质点,它的运动轨迹(即题目中描述的 Z 字形,但我觉得它更像 N 字形一点)就像上图描述的一样,不过这时竖轴就是这个字符在Z字形中的行数,横轴没有实际意义。

所以模拟这个往复运动的过程就能将字符按Z字形分到不同的行上,然后将每行组成的小字符串按照行数的顺序拼接在一起,组成最终的大字符串。

遍历原字符串,字符的行数是从小到大、然后再从大到小的,调转的时机就是 行数为0(波峰) 和 行数为numRows - 1(波谷)

将字符分到不同行时可以使用 S t r i n g B u i l d e r StringBuilder StringBuilder,本题解使用了一个 S t r i n g B u i l d e r StringBuilder StringBuilder数组,每个 S t r i n g B u i l d e r StringBuilder StringBuilder都记录了一行字符,在将所有字符都分到对应的行之后,按顺序将所有行合并到一起。

代码

java 复制代码
class Solution {
    public String convert(String s, int numRows) {
        // 如果numRows比2小,则不需要改变,直接返回原字符串即可
        if (numRows < 2) {
            return s;
        }

        // 先初始化numRows个StringBuilder,每个StringBuilder都代表一行
        StringBuilder[] builders = new StringBuilder[numRows];
        for (int i = 0; i < numRows; i++) {
            builders[i] = new StringBuilder();
        }

        int i = 0; // i是填充字符的行数
        int flag = -1; // flag是方向,要么为上: -1,要么为下: 1
        for (char c : s.toCharArray()) {
            builders[i].append(c);
            if (i == 0 || i == numRows - 1) { // 若行数为 第一行 或 最后一行
                flag = -flag; // 则调转填充字符的方向
            }
            i += flag; // 调整行数
        }
        
        // 按顺序合并StringBuilder的字符串
        StringBuilder res = new StringBuilder();
        for (StringBuilder builder : builders) {
            res.append(builder);
        }
        return res.toString();
    }
}

138. 随机链表的复制

题目链接

138. 随机链表的复制

标签

哈希表 链表

思路

先讲一讲什么叫做浅拷贝和深拷贝,实际上这两个概念很简单,浅拷贝就是拷贝后的对象和原来的对象指向同一块内存,而深拷贝是拷贝后的对象和原来的对象指向不同的内存。

本题可以使用旧节点和新节点的映射,key为旧节点,value为新节点。遍历两遍链表,第一遍先创建新节点,并建立映射;第二遍给新节点的next, random赋值,这时就可以从映射中获取旧节点对应的新节点,从而实现深拷贝。

代码

java 复制代码
class Solution {
    // 旧节点与新节点的映射,key为旧节点,value为新节点
    private final Map<Node, Node> mapper = new HashMap<>();
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        // 创建新节点,建立映射
        for (Node curr = head; curr != null; curr = curr.next) {
            mapper.put(curr, new Node(curr.val));
        }
        // 为新节点的next和random赋值
        for (Node curr = head; curr != null; curr = curr.next) {
            Node newNode = mapper.get(curr);
            newNode.next =  mapper.get(curr.next);
            newNode.random = mapper.get(curr.random);
        }
        // 返回第一个新节点
        return mapper.get(head);
    }
}
相关推荐
无籽西瓜a4 分钟前
【西瓜带你学设计模式 | 第十八期 - 命令模式】命令模式 —— 请求封装与撤销实现、优缺点与适用场景
java·后端·设计模式·软件工程·命令模式
郝学胜-神的一滴6 分钟前
ReLU激活函数全解析:从原理到实战,解锁深度学习核心激活单元
人工智能·pytorch·python·深度学习·算法
aXin_ya7 分钟前
微服务 第二天
java·数据库·微服务
AGV算法笔记11 分钟前
最新感知算法论文分析:RaCFormer 如何提升雷达相机 3D 目标检测性能?
数码相机·算法·3d·自动驾驶·机器人视觉·3d目标检测·感知算法
希望永不加班12 分钟前
Spring AOP 核心概念:切面、通知、切点、织入
java·数据库·后端·mysql·spring
脱氧核糖核酸__12 分钟前
LeetCode热题100——54.螺旋矩阵(题解+答案+要点)
c++·算法·leetcode·矩阵
lxh011318 分钟前
电话号码的字母组合
java·javascript·算法
爱学习的小可爱卢20 分钟前
算法—Java Map 核心方法与实战场景指南
java·开发语言·算法
WWZZ202520 分钟前
Sim2Sim理论与实践3:深度强化学习
人工智能·算法·机器人·深度强化学习·具身智能·四足·人形
会编程的土豆21 分钟前
【数据结构与算法】栈的应用
数据结构·c++·算法