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 ...
随机推荐
- 1002. 写出这个数 (20)-PAT乙级真题
读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字.输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式:在一行内输出n的各位数字之和的每一 ...
- Java 8 Optional:优雅地避免 NPE
本篇文章将详细介绍 Optional 类,以及如何用它消除代码中的 null 检查.在开始之前首先来看下什么是 NPE,以及在 Java 8 之前是如何处理 NPE 问题的. 空指针异常(NullPo ...
- pycharm2018.2汉化 解决设置打不开问题
首先检查下是不是装了中文汉化包resources_cn.jar 如果有的话,解决办法:1.更换一个汉化包或者将原来的resources_en.jar也放进lib目录下 2.将汉化包都删除,只留下原版的 ...
- SQL注入学习(一)
SQL注入(SQL Injection)是一种常见的Web安全漏洞,攻击者利用这个漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击. SQL注入基础 漏洞原理 针对SQL注入的攻击行为可描述 ...
- 使用SQLserver Management Studio连接VS2012自带数据库
下载 Microsoft® SQL Server® 2008 Management Studio Express http://www.microsoft.com/zh-CN/download/det ...
- win8 批处理自动填写ip
本文适用于,经常把电脑来回带而又每次都得改ip的人 有木有觉得,这很麻烦,而又必须得这样做? 人真是因为懒惰而变得聪明.如果你不想每次重复填写,有幸百度到了这篇文章,感谢你的阅读. 现在我把研究成果共 ...
- day07整理(内置方法\循环判断)
目录 一.上节课回顾 (一)if判断 1.单分支结构 2.双分支结构 3.多分支结构 (二)for循环 1.for + break 2.for + continue 3.for循环嵌套 (三)robu ...
- python的多线程和多进程(一)
在进入主题之前,我们先学习一下并发和并行的概念: --并发:在操作系统中,并发是指一个时间段中有几个程序都处于启动到运行完毕之间,且这几个程序都是在同一个处理机上运行.但任一时刻点上只有一个程序在处理 ...
- Elasticsearch 知识点整理 一
极力推荐: 官网地址: https://www.elastic.co/guide/en/elasticsearch/reference/6.0 肺腑之言,学ES先学原生的语法,SpringData封装 ...
- ubuntu 制作本地yum仓库
ubuntu 制作本地yum仓库 笔者: 张首富 W X: y18163201(请备注) qq群:895291458 时间:2019-01-31晚 今天到某银行进行软件部署的时候,碰到所有电脑都不允许 ...