python经典面试算法题1.4:如何对链表进行重新排序
本题目摘自《Python程序员面试算法宝典》,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中。
1.4 对链表按照如下要求重新排序
【微软笔试题】
难度系数:⭐⭐⭐
考察频率:⭐⭐⭐⭐
题目描述:
给定链表L0 -> L1 -> L2 -> … -> Ln-1 -> Ln ,把链表重新排序为 L0 -> Ln -> L1 -> Ln-1 -> L2 … 。要求:(1)在原来链表的基础上进行排序,即不能申请新的结点;(2)只能修改结点的next域,不能修改数据域。
分析解答:
当我们在笔试过程中遇到这种问题,一下子是没有什么思路的,我们要做的方法是把复杂问题拆解为简单问题。
就这一题而言我们可以把它分为三个步骤,(1)首先找到链表的中间结点;(2)对链表的后半部分子链表进行逆序;(3)把链表的前半部分子链表与逆序后的后半部分子链表进行合并,这里合并的思路是分别从两个链表各取一个结点进行合并。
步骤一
我们使用两个指针从链表的第一个结点开始同时遍历,快指针每次走两步,慢指针每次走一步,当快指针到达链表尾部时,慢指针恰好到达链表中部。
def find_mid_node(head):
if head is None or head.next is None:
return head
fast = head
slow = head
prev = slow
while fast is not None and fast.next is not None:
fast = fast.next.next
prev = slow
slow = slow.next
prev.next = None
return slow # 下半段的head
步骤二
这一步在我前面的博客文章中有写,可以点击此处跳转。
def reverse(head): #
p = head
if p is None or p.next is None:
return p
q = p
p = p.next
while p is not None:
tmp = p.next
p.next = q
if q == head:
q.next = None
q = p
p = tmp
return q
步骤三
这个函数传入前半部分的第一个结点和后半部分的第一个结点,cur1指向前半部分的第一个结点,cur2指向后半部分的第一个结点,tmp指向cur1后面的结点,然后令cur1的next指向cur2,接着cur1后移指向此时的tmp,然后让tmp再指向记住cur2的后面一个结点,令cur2的next指向此时的cur1,这样我们就完成了后半部分的第一个结点插入到前半部分,就这样一直往后,直到cur1到达最后一个结点,全部结点插入完成。
# 插入
def reorder(head1, head2):
cur1 = head1
cur2 = head2
tmp = None
while cur1.next is not None:
tmp = cur1.next
cur1.next = cur2
cur1 = tmp
tmp = cur2.next
cur2.next = cur1
cur2 = tmp
cur1.next = cur2 # 无论cur2是不是None,cur的next都应该指向cur2
把三个函数封装到一个类中
我们定义一个类,把上面三个函数都放在类中,并且令类的实例变成可调用对象。
class ReorderLink:
@staticmethod
def find_mid_node(head):
if head is None or head.next is None:
return head
fast = head
slow = head
prev = slow
while fast is not None and fast.next is not None:
fast = fast.next.next
prev = slow
slow = slow.next
prev.next = None
return slow # 下半段的head
@staticmethod
def reverse(head): #
p = head
if p is None or p.next is None:
return p
q = p
p = p.next
while p is not None:
tmp = p.next
p.next = q
if q == head:
q.next = None
q = p
p = tmp
return q
@staticmethod
def reorder(head1, head2):
cur1 = head1
cur2 = head2
tmp = None
while cur1.next is not None:
tmp = cur1.next
cur1.next = cur2
cur1 = tmp
tmp = cur2.next
cur2.next = cur1
cur2 = tmp
cur1.next = cur2 # 无论cur2是不是None,cur的next都应该指向cur2
def __call__(self, link_head):
before = link_head
rest =self.find_mid_node(before)
rest = self.reverse(rest) # 反转
self.reorder(before, rest)
return link_head
测试
构造一个链表,创建一个类的实例,调用类的实例。
class Node: # 结点类
def __init__(self, data=None):
self.data = data
self.next = None
class LinkList: # 链表
def __init__(self):
self.head = None
def append(self, x):
if self.head is None:
self.head = Node(x)
return self
p = self.head
while p.next is not None:
p = p.next
p.next = Node(x)
return self
link1 = LinkList()
link1.append(1).append(2).append(3).append(4).append(5).append(6)
head9 = link1.head
p = head9
print("排序前: ", end=" ")
while p is not None:
print(p.data, end="\t")
p = p.next
instance = ReorderLink() # 实例
head9 = instance(head9) # 实例可调用
print()
p = head9
print("排序后: ", end=" ")
while p is not None:
print(p.data, end="\t")
p = p.next
最后:
if hasattr(reader, "QQ"):
print(f"请{reader}加入交流群:6259 88679 !")
python经典面试算法题1.4:如何对链表进行重新排序的更多相关文章
- python经典面试算法题1.3:如何计算两个单链表所代表的数之和
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.2 如何实现链表的逆序 [华为笔试题] 难度系数:⭐⭐⭐ ...
- python经典面试算法题1.2:如何从无序链表中移除重复项
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.2 如何实现链表的逆序 [蚂蚁金服面试题] 难度系数:⭐⭐ ...
- python经典面试算法题4.1:如何找出数组中唯一的重复元素
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. [百度面试题] 难度系数:⭐⭐⭐ 考察频率:⭐⭐⭐⭐ 题目描述 ...
- python经典面试算法题1.1:如何实现链表的逆序
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.1 如何实现链表的逆序 [腾讯笔试题] 难度系数:⭐⭐⭐ ...
- C++经典面试算法题
转自:http://blog.csdn.net/f_r_e_e_x/article/details/50770907 //1.实现strcpy. char* MyStrCpy( char *pDest ...
- 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案
2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...
- python 经典排序算法
python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...
- 合并K个有序数组(链表)【字节跳动面试算法题】
本题是本人字节跳动一面考的算法题原题是有序数组,一时没想到怎么解决数组的问题,但是如果给的是有序链表数组,则可以用下面的方法解决 可以利用最小堆完成,时间复杂度是O(nklogk),具体过程如下: 创 ...
- 剑指offer中经典的算法题之从头到尾打印链表
话不多说上代码: 我自己的算法是: /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int ...
随机推荐
- Docker 配置国内镜像
前言 当我们使用Docker pull 拉取镜像时,有时候因网络问题,导致获取镜像报错,如下 :Error response from daemon:Get https://registry-1.co ...
- BZOJ 4621: Tc605
Description 最初你有一个长度为 N 的数字序列 A.为了方便起见,序列 A 是一个排列. 你可以操作最多 K 次.每一次操作你可以先选定一个 A 的一个子串,然后将这个子串的数字全部变成原 ...
- 【bzoj2342】[Shoi2011]双倍回文
这题属于博主还未填坑系列,先嘴巴AC,到时候有时间再搞字符串时,再来好好填坑. 废话不多说上题: 题解: 显然是和马拉车有关的吧,我们可以先对整个串跑一个马拉车,然后枚举‘#’好字符,并以他为中心,在 ...
- /usr/local/lib/ruby/gems/2.4.0/gems/cocoapods-1.5.3/lib/cocoapods/command.rb:118:in `git_version': Failed to extract git version from `git --version`
问题及分析 今天做项目的时候,执行pod update报了如下错误信息: /usr/local/lib/ruby/gems/2.4.0/gems/cocoapods-1.5.3/lib/cocoapo ...
- 尹吉峰:使用 OpenResty 搭建高性能 Web 应用
2019 年 8 月 31 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·成都站,原贝壳找房基础架构部工程师尹吉峰在活动上做了<使用 O ...
- tp5中使用中间控制器代理路由,以避免创建过多的无用控制器方法
在写项目的时候偶尔会加载一些不需要传递参数的静态视图,例如 class Index extends Common { public function index() { return $this-&g ...
- git的下载及简单使用一
git 是世界上最先进的分布式版本控制系统 常用的git网站 GitHub gitee(码云) git的下载地址 https://git-scm.com/downloads 而后根据计算机的系统选择相 ...
- Microsoft Word 2019 mac破解版下载
Microsoft Word 2019 Mac版是大名鼎鼎的Office办公软件组件之一,能帮助你进行文字排版,可方便的进行创作项目.作业.信件.博客.剧本.笔记.评论文章或简历. Microsoft ...
- 懒要懒到底,能自动的就不要手动,Hibernate正向工程完成Oracle数据库到MySql数据库转换(含字段转换、注释)
需求描述 需求是这样的:因为我们目前的一个老项目是Oracle数据库的,这个库呢,数据库是没有注释的,而且字段名和表名都是大写风格,比如 在代码层面的po呢,以前也是没有任何注释的,但是经过这些年,大 ...
- JetBrains系列软件激活码
T3ACKYHDVF-eyJsaWNlbnNlSWQiOiJUM0FDS1lIRFZGIiwibGljZW5zZWVOYW1lIjoi5bCP6bifIOeoi+W6j+WRmCIsImFzc2lnb ...