ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LeetCode 626 换座位

LeetCode 626 换座位 LeetCode 626 换座位Exchange Seats原题标签数据库原题目是SQL题下面我用费曼学习法拆解同时用Pythonpandas来模拟数据库表完成解题。一、题目原文题目编号626. 换座位表SeatColumn NameTypeidintstudentvarcharid是该表主键唯一。每一行代表学生姓名和座位ID。id 序列从1开始连续无空缺。需求描述交换每两个连续学生的座位。如果学生总数是奇数最后一名学生座位不交换。结果表按 id 升序返回。示例1输入 Seatidstudent1Abbot2Doris3Emerson4Green5Jeames输出idstudent1Doris2Abbot3Green4Emerson5Jeames解释1和2互换3和4互换总人数5是奇数id5不动。二、费曼学习法破解思路用大白话讲明白费曼学习核心把复杂问题翻译成普通人听得懂的语言再提炼规则再验证边界第一步通俗理解问题想象一排座位编号1,2,3,4,5……两个人一组互换座位第1个人和第2个人交换名字第3个人和第4个人交换名字第5个人没有下一个搭档原地不动⚠️关键点我们不是修改id而是保持id不变把对应student名字互换。id永远1,2,3,4,5顺序不变只是每个id对应的学生名字换掉。第二步提炼数学规则核心公式总人数n对每一行的id如果id 是奇数并且id 不是最后一个id→ 这个id要拿 id1 的学生名字如果 id 是最后一个奇数→ 名字不变如果id 是偶数直接拿 id-1 的学生名字一句话口诀奇数找下一位偶数找上一位最后一位奇数不动。示例验证n5id1奇数不是最后 → student取id2Dorisid2偶数 → student取id1Abbotid3奇数不是最后 → student取id4Greenid4偶数 → student取id3Emersonid5奇数是最后 → student不变 Jeames✅ 和样例输出完全一致第三步思考实现方案两种解法解法1遍历条件判断基础版把数据放进列表循环每一条id根据奇偶判断取哪个位置的学生名字。适合理解原理。解法2pandas向量化条件工业版模拟数据库CASE WHEN类似SQL的case when一次性批量计算不写循环和原题SQL思路一一对应。第四步边界测试费曼必须检查边界测试用例1n1只有1个学生 → 直接原样输出测试用例2n2两个人 → 互相交换测试用例3n4偶数总数 → 1↔23↔4全部交换三、Python代码实现 每行详细注释使用 pandas 模拟数据库表LeetCode数据库题目Python最常用模拟方式先【基础遍历解法】再【pandas向量化解法】解法1基础列表遍历最容易看懂defexchange_seat(seat_list): seat_list: 输入列表元素为元组 (id, student) 返回新列表按id升序完成座位交换 思路把列表转成字典方便通过id快速查找学生名字 # 1. 拿到总人数nlen(seat_list)# 2. 构建id - student 的字典O(1)查找名字id_to_student{}for_id,nameinseat_list:id_to_student[_id]name# 准备存储结果result[]# 遍历每一个idid连续从1到nforcurrent_idinrange(1,n1):# 判断当前id是奇数还是偶数ifcurrent_id%21:# 当前id是奇数ifcurrent_idn:# 奇数并且是最后一个名字不变new_nameid_to_student[current_id]else:# 不是最后一个奇数取下一个id(current_id1)的名字new_nameid_to_student[current_id1]else:# 当前id是偶数取前一个id(current_id-1)的名字new_nameid_to_student[current_id-1]# 添加到结果id不变名字换成new_nameresult.append((current_id,new_name))returnresult# 样例测试 if__name____main__:# 输入样例模拟数据库Seat表input_seat[(1,Abbot),(2,Doris),(3,Emerson),(4,Green),(5,Jeames)]# 调用函数outputexchange_seat(input_seat)# 打印输出print(id | student)print(---|--------)for_id,nameinoutput:print(f{_id}|{name})运行输出id | student ---|-------- 1 | Doris 2 | Abbot 3 | Green 4 | Emerson 5 | Jeames解法2Pandas向量化写法对标SQL原题工程常用importpandasaspddefexchange_seats_pandas(seat_df:pd.DataFrame)-pd.DataFrame: 输入pandas dataframe列id, student模拟数据库表 返回交换座位后的df按id升序 等价SQL CASE WHEN逻辑 # 获取总学生数量totalseat_df[id].max()# 新建结果df直接复制原表res_dfseat_df.copy()# 定义条件逻辑批量生成新student名字defget_new_name(row):cidrow[id]ifcid%21:ifcidtotal:# 最后奇数不动returnrow[student]else:# 奇数取cid1的学生returnseat_df.loc[seat_df[id]cid1,student].values[0]else:# 偶数取cid-1的学生returnseat_df.loc[seat_df[id]cid-1,student].values[0]# apply逐行执行上面函数res_df[student]res_df.apply(get_new_name,axis1)# 按id升序排序题目强制要求res_dfres_df.sort_values(id).reset_index(dropTrue)returnres_df# 测试主程序if__name____main__:data{id:[1,2,3,4,5],student:[Abbot,Doris,Emerson,Green,Jeames]}dfpd.DataFrame(data)ans_dfexchange_seats_pandas(df)print(ans_df)上面pandas写法完全等价原题SQL CASE WHEN方案面试如果问SQL逻辑一模一样。四、应用场景举例这个题目表面是座位交换本质是有序序列相邻两两交换最后单数元素保留真实业务场景场景1线上考场座位编排系统在线考试系统随机分配座位后老师想要两两相邻考生互换位置总人数奇数最后一位不动。数据存储在MySQL业务代码可以用SQL或者Python pandas做座位调换展示。场景2直播间观众分组直播间观众排队列表两两一组互换位置展示用来做配对抽奖人数奇数最后一人单独一组不交换。场景3设备巡检顺序调整巡检设备编号1,2,3,4,5巡检顺序两两调换奇数总数最后设备顺序不变。场景4报表展示顺序调整报表行记录两两交换展示但是主键id保持不变只交换展示内容和本题完全一致。五、费曼复盘总结一句话总结id保持不变奇数id只要不是最后一个就拿下一个人的名字偶数id永远拿前一个人的名字最后一个奇数id不动。这个题的坑很多人会想着交换id但是题目要求id列保持1,2,3,4,5不变交换的是student名字。
返回列表