欢迎关注微信公众号:简说Python
关注后回复:1024,可以领取精选编程学习电子书籍。
这两天和几个朋友组了个互相督促学习群,想着督促一下自己学习,也督促自己的原创输出,其实很多时候都是懒,真不是没有东西可以写了,这不,我在我的免费知识星球简说编程里开了个新的标签日常编程问题,后面我会把自己学习工作中遇到的一些问题和解决方法记录到里面,有些可以扩展的点,我会写到微信公众号里。
我定的目标是:
我简单写了个规则,大家说可以,然后,我们就开始吧,我习惯把该做的事情提前一天做(如果有时间的话)。
今天给大家分享的书籍《Python程序员面试算法宝典》第一章第七小节:翻转链表相邻结点。
如果你是第一次看,也许,你可以看看本系列下面的文章:
Smaller And Smarter Python数据结构:链表逆转
Smaller And Smarter Python数据结构:删除无序链表重复结点
Smaller And Smarter Python数据结构:链表相加
Smaller And Smarter Python数据结构:链表进行重新排序
Smaller And Smarter Python数据结构:链表倒数第K个元素+检测单链表环
"""
目标:写一段程序,翻转链表相邻结点
例如:
输入-> 1->2->3->4->5
输出-> 2->1->4->3->5
Goal: write a program to flip the adjacent nodes of the linked list
For example:
Input - > 1 - > 2 - > 3 - > 4 - > 5
Output - > 2 - > 1 - > 4 - > 3 - > 5
"""
首先我们写好链表的基本操作,在a_0_base.py文件中,目前包含对链表的定义类,初始化函数,遍历函数。(带头结点)
# -*- coding: utf-8 -*-
"""
@author = 老表
@date = 2019-10-19
@个人微信公众号 : 简说Python
"""
# 链表数据结构定义
class ListNode:
def __init__(self, x):
self.data = x
self.next = None
class ListOperation:
# 根据链表数据初始化链表
@staticmethod
def init_list(n_list):
# 初始化一个头指针
head = ListNode("head")
cur = head
for i in n_list:
node = ListNode(i)
cur.next = node
cur = node # 相当于 cur = cur.next,后移
return head
# 遍历链表,带头结点
@staticmethod
def ergodic_list(head):
cur = head.next
while cur:
print(cur.data)
cur = cur.next
# 获取链表长度
@staticmethod
def get_len_list(head):
cur = head.next
len_list = 0
while cur:
len_list = len_list + 1
cur = cur.next
return len_list
开始程序前需提前导入前面写好的链表基本操作包和结点数据结构,在Linked_list的a_0_base.py中。
from Linked_list.a_0_base import ListOperation
"""
Method One : 遍历交换法
核心思想:遍历链表,记录从往后,记录相邻的两个结点,
改变结点指向,实现交换(实际需要四个结点,比如:
a->b->c->d b,c 交换,要修改三处链表指向
故a,b,c,d四个结点都要记录)。
时间复杂度:O(N)
空间复杂度:O(1)
"""
def flip_adjacent_node_one(head):
if not head.next: # 空链表
return head # 返回头结点
pre_node = head # 记录前驱结点
cur_node = head.next # 记录当前结点
while cur_node.next: # 遍历交换(cur_node 与 cur_node.next交换)
next_node = cur_node.next.next
# 记录下一个cur_node,因为相邻交换没两个进行一次,故下一个为cur_node.next.next
pre_node.next = cur_node.next
# 1、交换第一步,前驱结点指向cur_node的后一个结点(cur_node.next)
cur_node.next.next = cur_node
# 2、交换第二步,cur_node.next反指,指向cur_node
cur_node.next = next_node
# 3、交换第三步,cur_node指向cur_node.next.next,完成交换
"""(原本是cur_node.next指向cur_node.next.next,
但现在cur_node与cur_node.next交换位置,
故让cur_node指向cur_node。next.next)"""
pre_node = cur_node
# 前驱结点后移
cur_node = next_node
# 当前结点后移
return head # 返回头结点
"""
Method Two :递归交换法
核心思想:遍历链表,每次将相邻结点的第二个结点的
next指针指向前一个结点,然后将第一个结点的指针指
向下一组已经翻转好的相邻结点的第一个结点。
时间复杂度:O(N)
空间复杂度:O(1)
"""
def flip_adjacent_node_two(head):
if not head: # 空链为空 或者 递归到尾
return head # 开始回溯,返回结点
if head.data == "head": # 去掉头结点,直接从第一个结点开始
head = head.next
first_node = head # 链表第一个结点
second_node = head.next # 获取第二个结点
first_node.next = flip_adjacent_node_two(head.next.next)
# 递归,传递第三个结点作为参数
# 回溯时,让第一个结点指向下一组已经翻转好的相邻结点的第一个结点
second_node.next = first_node
# 回溯时,让第二个结点反指向第一个结点
return second_node # 返回头结点
本文代码思路部分来自书籍《Python程序员面试宝典》,书中部分代码有问题或未提供代码,文中已经修改过了,并添加上了丰厚的注释,方便大家学习,后面我会把所有内容开源放到Github上,包括代码,思路,算法图解(手绘或者电脑画),时间充裕的话,会录制视频。
希望大家多多支持。
大家好,我是老表
觉得本文不错的话,转发、留言、点赞,是对我最大的支持。
欢迎关注微信公众号:简说Python
关注后回复:1024,可以领取精选编程学习电子书籍。