单链表反转的原理和python代码实现
链表是一种基础的数据结构,也是算法学习的重中之重。其中单链表反转是一个经常会被考察到的知识点。
单链表反转是将一个给定顺序的单链表通过算法转为逆序排列,尽管听起来很简单,但要通过算法实现也并不是非常容易。现在来给大家简单介绍一下单链表反转算法实现的基本原理和python代码实现。
算法基本原理及python代码
1、方法一:三个指针遍历反转
算法思想:使用3个指针遍历单链表,逐个链接点进行反转。
(1)分别用p,q两个指针指定前后两个节点。其中p.next = q
(2)将p指针指向反方向。
(3)将q指针指向p。q.next = p,同时用r代表剩余未反转节点。
(4)将p,q指针同时后移一位,回到步骤(2)的状态。
(5)r指针指向剩余未反转节点。循环执行(3)之后的操作。
# 详细版
def reverse01(head):
if head == None:
return None
# 分别用p,q两个指针指定先后两个节点
p = head
q = head.next
# 将p节点反转,head节点只能指向None
p.next = None
# 当存在多个后续节点时,循环执行
while q:
r = q.next # 用r表示后面未反转节点
q.next = p # q节点反转指向p
p = q
q = r # p,q节点后移一位,循环执行后面的操作
return p
# 精简版
def reverse01(head):
if not head:
return None
p,q,p.next = head,head.next,None
while q:
q.next,p,q = p,q,q.next
return p
2、方法二:尾插法反转
算法思想:固定头节点,然后将后面的节点从前到后依此插入到次节点的位置,最后再将头节点移动到尾部。
# 详细版
def reverse02(head):
# 判断链表的节点个数
if head == None or head.next == None:
return head
p = head.next
# 循环反转
while p.next:
q = p.next
p.next = q.next
q.next = head.next
head.next = q
# 将头节点移动到尾部
p.next = head
head = head.next
p.next.next = None
return head
# 精简版
def reverse02(head):
if not head or not head.next:
return head
p = head.next
while p.next:
q = p.next
p.next,q.next,head.next = q.next,head.next,q
p.next,head,p.next.next = head,head.next,None
return head
3、方法三:递归方式反转
算法思想:把单链表的反转看作头节点head和后续节点head.next之间的反转,循环递归。
def reverse03(head):
if head.next == None:
return head
new_head = reverse03(head.next)
head.next.next = head
head.next = None
return new_head
leetcode精简代码示例
单链表的反转逻辑思路比较清晰,因此关于单链表反转重在考查代码的经精简度,而Python可以实现代码的极度简化,如下:
def reverse04(head):
curr,pre = head,None
while curr:
curr.next,pre,curr = pre,curr,curr.next
return pre
leetcode相关算法习题(92.反转链表II)
利用以上算法思想完成leetcode习题:92.反转链表II
习题描述:
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
# 算法思想:采用尾插法反转思想(方法二)
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseBetween(self, head, m, n):
"""
:type head: ListNode
:type m: int
:type n: int
:rtype: ListNode
"""
root = ListNode(0)
root.next = head
Head = root # 指定一个头部变量(方法二中固定的head)
for i in range(m-1):
Head = Head.next
if Head.next == None:
return head
pre = Head.next
while pre.next and m < n:
curr = pre.next
pre.next = curr.next
curr.next = Head.next
Head.next = curr
m += 1
# 由于m之前的元素不需要反转,因此用root.next代替方法二中的head
return root.next
单链表反转的原理和python代码实现的更多相关文章
- woe_iv原理和python代码建模
python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...
- 线性插值法的原理和python代码实现
假设我们已知坐标 (x0, y0) 与 (x1, y1),要得到 [x0, x1] 区间内某一位置 x 在直线上的值.根据图中所示,我们得到 由于 x 值已知,所以可以从公式得到 y 的值 已知 y ...
- k-means原理和python代码实现
k-means:是无监督的分类算法 k代表要分的类数,即要将数据聚为k类; means是均值,代表着聚类中心的迭代策略. k-means算法思想: (1)随机选取k个聚类中心(一般在样本集中选取,也可 ...
- python实现单链表反转(经典笔试题)
https://blog.csdn.net/su_bao/article/details/81072849 0.说在前面的话 链表结构,说难不难,说易不易,一定要亲自编程实现一下.其次就是一定要耐心, ...
- 单链表反转java代码
据说单链表反转问题面试中经常问,而链表这个东西相对于数组的确稍微难想象,因此今天纪录一下单链表反转的代码. 1,先定义一个节点类. public class Node { int index; Nod ...
- Java单链表反转 详细过程
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/guyuealian/article/details/51119499 Java单链表反转 Java实 ...
- Java单链表反转图文详解
Java单链表反转图文详解 最近在回顾链表反转问题中,突然有一些新的发现和收获,特此整理一下,与大家分享 背景回顾 单链表的存储结构如图: 数据域存放数据元素,指针域存放后继结点地址 我们以一条 N1 ...
- java实现单链表反转(倒置)
据说单链表反转问题面试中经常问,而链表这个东西相对于数组的确稍微难想象,因此今天纪录一下单链表反转的代码. 1,先定义一个节点类. 1 public class Node { 2 int index; ...
- java单链表反转
今天做leetcode,遇到了单链表反转.研究了半天还搞的不是太懂,先做个笔记吧 参考:http://blog.csdn.net/guyuealian/article/details/51119499 ...
随机推荐
- 吴裕雄--天生自然python学习笔记:Python MongoDB
MongoDB 是目前最流行的 NoSQL 数据库之一,使用的数据类型 BSON(类似 JSON). PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动,这里我们使用 P ...
- 关于JavaScript中的typeof与instanceof
JavaScript中typeof和instanceof可以用来判断一个数据的类型,什么时候选择使用typeof?什么时候选择使用instanceof? typeof运算符 typeof运算符返回值有 ...
- 签名旧版的pom文件
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven ...
- 访问Http接口的两种请求方式
1. POST方式请求 public void testPostLogin() throws Exception{ String url = "http://192.168.1.160:80 ...
- 使用 JavaScript 创建并下载文件
先上代码 Blob 对象 Blob URLs 模拟 click 小结 参考 本文将介绍如何使用 JavaScript 创建文件,并自动/手动将文件下载.这在导出原始数据时会比较方便. 先上代码 /** ...
- 你每天跑这么多自动化用例,能发现BUG吗?
阿里QA导读:为什么要度量测试有效性?这么多的CASE,花了大量时间和资源去运行,真能发现bug吗?CI做到90%的行覆盖率了,能发现问题吗?测试用例越来越多,删一些,会不会就发现不了问题了?怎么找出 ...
- Android apk签名详解——AS签名、获取签名信息、系统签名、命令行签名
Apk签名,每一个Android开发者都不陌生.它就是对我们的apk加了一个校验参数,防止apk被掉包.一开始做Android开发,就接触到了apk签名:后来在微信开放平台.高德地图等平台注册时,需要 ...
- 致歉Note7用户后,三星要还给世界下一个机皇
1月23日,三星电子在韩国首尔公布了Note7事件原因调查结果.此次认定过程精密而繁琐,最终结果发布距离三星宣布全球召回Note7已经有3个月. 相比事发之初各路信息甚嚣尘上,现在虽然还不能说已经 ...
- hadoop地址配置、内存配置、守护进程设置、环境设置
1.1 hadoop配置 hadoop配置文件在安装包的etc/hadoop目录下,但是为了方便升级,配置不被覆盖一般放在其他地方,并用环境变量HADOOP_CONF_DIR指定目录. 1.1.1 ...
- sql--测试商品的重要度,是否需要及时补货
表1:商品表 表2:商品售卖表 需求:算出商品的平均点击率.平均销售.商品受欢迎度 1.使用inner join查出每件商品的点击率和销售额度 ) as selas from test a left ...