LeetCode:626.换座位
题目
小美是一所中学的信息科技老师,她有一张 seat
座位表,平时用来储存学生名字和与他们相对应的座位 id
。
其中纵列的 id
是连续递增的
小美想改变相邻俩学生的座位。
你能不能帮她写一个 SQL query 来输出小美想要的结果呢?
示例:
+---------+---------+
| id | student |
+---------+---------+
| 1 | Abbot |
| 2 | Doris |
| 3 | Emerson |
| 4 | Green |
| 5 | Jeames |
+---------+---------+
假如数据输入的是上表,则输出结果如下:
+---------+---------+
| id | student |
+---------+---------+
| 1 | Doris |
| 2 | Abbot |
| 3 | Green |
| 4 | Emerson |
| 5 | Jeames |
+---------+---------+
注意:
如果学生人数是奇数,则不需要改变最后一个同学的座位。
解答
解法一
根据自己的逻辑尝试了一下,居然提交通过,哈哈!
---- MySQL ----
# Write your MySQL query statement below
select case when b.cnt % 2 = 0 then
case when a.id % 2 = 0 then id - 1
when a.id % 2 = 1 then id + 1 end
when b.cnt % 2 = 1 then
case when a.id < b.cnt then
case when a.id % 2 = 0 then id - 1
when a.id % 2 = 1 then id + 1 end
else id end
end as id,
student
from seat a,
(
select count(*) as cnt
from seat
) b
order by id; ---- 126ms
引入总行数计数 cnt
,作为另外一个表;
判断当前行数是偶数还是奇数,再判断当前 id
是奇数还是偶数,奇数+1,偶数 -1,依次类推;
当行数为奇数时,最后一行 id
不作任何操作。
简化一下。
---- MySQL ----
# Write your MySQL query statement below
select if(id % 2 = 0,
id - 1,
if(id = cnt,
id,
id + 1
)
) as id,
student
from
(
select count(*) as cnt from seat
) as a,
seat
order by id; ---- 133ms
另一种。
---- MySQL ----
# Write your MySQL query statement below
select (case when id % 2 = 0 then id -1
when id = (select max(id) from seat) then id
else id + 1 end) as id,
student
from seat
order by id; ---- 156ms
解法二
通过左连接的方法。
---- MySQL ----
# Write your MySQL query statement below
select a.id,
ifnull(b.student, a.student) as student
from seat a
left join seat b
on (a.id % 2 = 1 && a.id = b.id -1) || (a.id % 2 = 0 && a.id = b.id + 1)
order by a.id ---- 135ms
真的很天才,佩服!
解法三
通过异或的方法,更是牛逼!
0 ^ 1 = 1
1 ^ 1 = 0
---- MySQL ----
select b.id,
a.student
from seat a,
seat b,
(select count(*) as cnt from seat) c
where b.id = 1 ^ (a.id - 1) + 1 || (c.cnt % 2 && b.id = c.cnt && a.id = c.cnt); ---- 132ms
如果是一个偶数^1,结果是偶数+1;
如果是一个奇数^1,结果是奇数-1;
(id -1 ) ^ 1 + 1
可以把1、2交换位置,3、4交换位置。
思考
MySQL
中的 ifnull()
函数用于判断第一个表达式是否为 null
,如果为 null
则返回第二个表达式的值。
异或操作,真是神,往往能达到意想不到的效果,get!