该系列博客内容主要是《剑指Offer》中的经典题目,结合在刷题过程中见到的一些精彩的解题过程,从而在这里记录下来。代码以Python3实现。
基础知识
所谓的基础知识在这里是一定要知道的,不然可能对于理解这道题会有一定的困难。
在C语言实现链表中,因为C有指针,可以很方便的控制内存,很方便实现链表。但Python是动态语言,可以直接把对象赋值给新的变量。在C/C++中,通常用“指针+结构体”来实现链表,而在Python中,则可以用“引用+类”来实现链表。
链表的定义:是一组数据项的集合,其中每个数据项都是一个节点的一部分,每个节点还包含指向下一个节点的地址。
链表的结构:data为自定义的数据,next为下一个节点的地址。
基本元素
1.节点:每个节点有两个部分,左边部分称为值域,用来存放用户数据;右边部分称为指针域,用来存放指向下一个元素的指针。
2.head:head节点永远指向第一个节点。
3.tail: tail永远指向最后一个节点。
4.None:链表中最后一个节点的指针域为None值。
解法1:利用外部空间
申请一个动态扩容的数组或者容器,然后不断遍历链表,将链表中的元素添加到这个容器中,然后利用容器自身的API,反转整个容器,这样就可以达到反转的效果。
代码如下
上述方法使用了外部空间,那么有没有方法用O(1)空间复杂度来实现呢?
解法二:双指针迭代
先把代码附上,我们边看代码边进行分析。
其实代码很简单,只是有些绕,while循环是主体部分。在这里,我们可以申请两个指针。第一个指针是last,最初是指向null的。第二个指针pHead指向头节点head。当每一次的循环的时候,都将pHead的next指向上一个节点last,然后last和pHead前进一步。
tmp = pHead.next
pHead.next = last
last = pHead
pHead = tmp
这几行代码的意思是我的last开始指向的是None,现在None给了pHead.next,所以原链表的第一个节点就断开了,这样就得到单独的一个节点的值,然后将原链表的pHead向后移动。
tmp = pHead.next
pHead.next = pHead
解法3 递归解法
Python反转链表
Python数据结构–链表(最简单的解释)