本题目摘自《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:如何对链表进行重新排序的更多相关文章

  1. python经典面试算法题1.3:如何计算两个单链表所代表的数之和

    本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.2 如何实现链表的逆序 [华为笔试题] 难度系数:⭐⭐⭐ ...

  2. python经典面试算法题1.2:如何从无序链表中移除重复项

    本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.2 如何实现链表的逆序 [蚂蚁金服面试题] 难度系数:⭐⭐ ...

  3. python经典面试算法题4.1:如何找出数组中唯一的重复元素

    本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. [百度面试题] 难度系数:⭐⭐⭐ 考察频率:⭐⭐⭐⭐ 题目描述 ...

  4. python经典面试算法题1.1:如何实现链表的逆序

    本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.1 如何实现链表的逆序 [腾讯笔试题] 难度系数:⭐⭐⭐ ...

  5. C++经典面试算法题

    转自:http://blog.csdn.net/f_r_e_e_x/article/details/50770907 //1.实现strcpy. char* MyStrCpy( char *pDest ...

  6. 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案

    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...

  7. python 经典排序算法

    python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...

  8. 合并K个有序数组(链表)【字节跳动面试算法题】

    本题是本人字节跳动一面考的算法题原题是有序数组,一时没想到怎么解决数组的问题,但是如果给的是有序链表数组,则可以用下面的方法解决 可以利用最小堆完成,时间复杂度是O(nklogk),具体过程如下: 创 ...

  9. 剑指offer中经典的算法题之从头到尾打印链表

    话不多说上代码: 我自己的算法是: /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int ...

随机推荐

  1. ionic3 浏览器端返回

    首屏component.ts文件中使用setupBrowserBackButtonBehavior() { // Register browser back button action(s) wind ...

  2. 原生js动态添加新元素、删除元素方法

    1. 添加新元素 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  3. MakaJs:基于 React, Redux 的轻量级前端框架

    github: maka.js 留下您宝贵的STAR!谢谢 maka maka源于中文码咖,意为写代码的大咖 一眼即可看懂的前端框架,简约而不简单 1.安装 bash sudo npm i -g @m ...

  4. Road Construction

    King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom. Amazin ...

  5. 利用pyecharts将数据可视化

    可视化展示在数据分析领域中是一个至关重要的点,好的可视化展示对我们的结果分析有更好的支持作用. 一.问题 在数据分析的时代里面我们需要将数据的可视化展现出来,更加方便用户的观察.如下图 有些时候我们需 ...

  6. 1002. 写出这个数 (20)-PAT乙级真题

    读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字.输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式:在一行内输出n的各位数字之和的每一 ...

  7. Android Studio 1.5运行问题

    Error:Unable to start the daemon process: could not reserve enough space for object heap.Please assi ...

  8. 【阿里云IoT+YF3300】6.物联网设备报警配置

    纵然5G时代已经在时代的浪潮中展现出了它的身影,但是就目前的物联网环境中,网络问题仍旧是一个比较突出的硬伤.众所周知,在当前的物联网规划中,与其说是实现万物互联,倒不如说是行业指标数据监控.对于一些特 ...

  9. photometric_stereo halcon光度立体法三维表面重建

    官方文档翻译 名称: photometric_stereo -- 通过光度立体技术重建表面. 签名: photometric_stereo(Images : HeightField, Gradient ...

  10. python-json与字典的区别

    1.字典的类型是字典dict,是一种数据结构:json的类型是字符串str,json是一种格式: 接口测试是传参数payload时有时候是传的字符串,应该将payload的类型改为json  这点要注 ...