【LeetCode-SQL】626. 换座位

这篇博客详细介绍了如何使用SQL解决LeetCode中的626题——交换每两个连续学生座位。作者探讨了四种不同的解决方案,包括if/case when、row_number()、left join以及异或操作,并提供了相应的代码示例。文章强调了针对不同情况(如座位数为奇数)的处理,并引用了其他相关资源作为参考。

一、题目

表: Seat

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
+-------------+---------+
Id是该表的主键列。
该表的每一行都表示学生的姓名和ID。
Id是一个连续的增量。

编写SQL查询来交换每两个连续的学生的座位号。如果学生的数量是奇数,则最后一个学生的id不交换。

id 升序 返回结果表。

查询结果格式如下所示。

示例 1:

输入: 
Seat:
+----+---------+
| id | student |
+----+---------+
| 1  | Abbot   |
| 2  | Doris   |
| 3  | Emerson |
| 4  | Green   |
| 5  | Jeames  |
+----+---------+
输出: 
+----+---------+
| id | student |
+----+---------+
| 1  | Doris   |
| 2  | Abbot   |
| 3  | Green   |
| 4  | Emerson |
| 5  | Jeames  |
+----+---------+
解释:
请注意,如果学生人数为奇数,则不需要更换最后一名学生的座位。

二、解决

1、if / case when

思路:

主要根据 id 的奇偶性进行处理,这里要注意 id 最大值为基数的情况。
if id 为偶数,then id - 1;
if id为奇数且不为最大值, then id + 1;
if id为奇数且为最大值then id 不变。

代码 - 版本1:

select 
    if (id%2=0, id-1, 
    	if(id=mxid, id, id+1)
    ) as id, student 
from seat, (select max(id) as mxid from seat) as init # 最大数为奇数
order by id;

代码 - 版本2:

select 
    case 
        when id % 2 = 0 then id - 1
        when id % 2 = 1 and id = mxid then id
        else id + 1
    end as id
    , student
from seat, (select max(id) as mxid from seat) as init # 最大数为奇数
order by id;

2、row_number()

思路:

row_number() 作用实例:

SELECT 
  name, recovery_model_desc
FROM sys.databases 
WHERE database_id < 5
ORDER BY name ASC;

Here is the result set.

namerecovery_model_desc
masterSIMPLE
modelFULL
msdbSIMPLE
tempdbSIMPLE
SELECT 
  ROW_NUMBER() OVER(PARTITION BY recovery_model_desc ORDER BY name ASC) 
    AS Row#,
  name, recovery_model_desc
FROM sys.databases WHERE database_id < 5;

Here is the result set.

Row#namerecovery_model_desc
1modelFULL
1masterSIMPLE
2msdbSIMPLE
3tempdbSIMPLE

代码:

select 
    row_number() over(order by (id + 1 - 2 * power(0, id%2))) as id,
    student
from 
    seat

说明:

select power(0, 1) as odd, power(0, 0) as even;

# res:
{"headers": ["odd", "even"], "values": [
	[0.0, 1.0]
]}

3、left join

思路:

select t1.id, t2.student, t1.student
from seat as t1 
left join seat as t2 on (t1.id%2=1 && t1.id=t2.id-1) || (t1.id%2=0 && t1.id=t2.id+1) 
order by t1.id;
a.idb.studenta.student
1DorisAbbot
2AbbotDoris
3GreenEmerson
4EmersonGreen
5nullJeames

代码:

select t1.id, ifnull(t2.student, t1.student) as student 
from seat as t1 
left join seat as t2 on (t1.id%2=1 && t1.id=t2.id-1) || (t1.id%2=0 && t1.id=t2.id+1) 
order by t1.id;

4、异或

思路: 0^1=1, 1^1=0, 2^1=3, 3^1=2,以此类推。
代码:

select b.id, a.student 
from seat as a, seat as b, (select count(*) as cnt from seat) as c 
where b.id = 1^(a.id-1) + 1
# where a.id=1^(b.id-1) + 1 # 也可以这样写,更容易理解. 
							# If b.id is 偶数, then b.id-1; 
							# If b.id is 奇数, then b.id+1; 
 || (c.cnt%2 && b.id=c.cnt && a.id=c.cnt);

三、参考

1、换座位
2、简单 易懂 效率击败所有
3、其实是一道中学数学题
4、626. 换座位[官方题解的坑要避免]
5、看到没有异或方法,我就知道我的机会来了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值