链表II

3、反转链表

反转一个单链表。

示例:
输入:1 -> 2 -> 3 -> 4 -> 5 -> NULL
输出:5 -> 4 -> 3 -> 2 -> 1 -> NULL

解法1:迭代

思路:从前往后遍历链表,定义3个指针分别指向相邻的三个节点,反转前两个节点,即让第二个节点指向第一个节点。然后一次往后移动指针,直到第二个节点为空结束。

class Solution:
    def reverseList(self, head):
    	preNode = None
    	while head:
    	    nextNode = head.next
    	    head.next = preNode
    	    preNode = head
    	    head = nextNode
    	return preNode

解法2:递归

基线条件:空链或只有一个节点,直接返回头指针
递归条件:递归调用,返回子链表反转后的头指针

class Solution:
    def reverseList(self, head):
    	if not head or not head.next:
    	    return head
    	nextNode = head.next
    	newHead = self.reverseList(nextNode)
    	nextNode.next = head
    	head.next = None
    	return newHead

4、合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:
输入:1 -> 2 -> 4, 1 -> 3 -> 4
输出:1 -> 1 -> 2 -> 3 -> 4 -> 4

解法1:

思路:创建一个新的链表,按顺序将 l 1 、 l 2 l1、l2 l1l2 接上。

class Solution:
    def mergeTwoLists(self, l1, l2):
    	head = ListNode(0)
    	newlist = head
    	while l1 and l2:
    	    if l1.val <= l2.val:
    	    	head.next = l1
    	    	l1 = l1.next
    	    else:
    	    	head.next = l2
    	    	l2 = l2.next
    	    head = head.next
    	head.next = l1 or l2
    	#newlist一直指着头部,从0开始,所以要从下一个开始return
    	return newlist.next 

解法2:递归

先判断 l 1 、 l 2 l1、l2 l1l2 是否为空的情况,若都不为空,再采用递归方法分别比较 l 1 、 l 2 l1、l2 l1l2 中的节点。

class Solution:
    def mergeTwoLists(self, l1, l2):
    	if l1 == None and l2 == None:
    	    return None
    	if l1 == None:
    	    return l2
    	if l2 == None:
    	    return l1
    	if l1.val <= l2.val:
    	    l1.next = self.mergeTwoLists(l1.next, l2)
    	    return l1
    	else:
    	    l2.next = self.mergeTwoLists(l1, l2.next)
    	    return l2

5、回文链表
请判断一个链表是否为回文链表。

示例1:
输入: 1 -> 2
输出:False

示例2:
输入:1 -> 2 -> 2 -> 1
输出:True

思路:

  1. 采用快慢指针找到链表中点:用追赶法,一个指针一次走两步,一个指针一次走一步;
  2. 找到中点后,将后半链表反转。
    注意:反转过程中,nextNode = slow.next一定要在第二句,而不是最好,不然会断链
  3. 判断链表是否为回文链表
class Solution:
    def isPalindrome(self, head):
    	fast = slow = head
    	while fast and fast.next:
    	    fast = fast.next.next
    	    slow = slow.next
    	
    	node = None
    	while slow:
    	    nextNode = slow.next
    	    slow.next = node
    	    node = slow
    	    slow = nextNode
	
	while node and head:
	    if node.val != head.val:
	    	return False
	    node = node.next
	    head = head.next
	return True

新建一个链表,判断反转后是否相等

class Solution:
    def isPalindrome(self, head):
    	stack = []
    	while head:
    	    stack.append(head.val)
    	    head = head.next
    	return stack == stack[::-1]
4、环形链表

给定一个链表,判断链表中是否有环。

设置两个指针slow和fast,一个步长为1、一个步长为2进行遍历。如果有环,slow和fast总会在某一点相遇;如果没有,则fast会先为空或fast.next为空。

class Solution(object):
    def hasCycle(self, head):
    	fast = slow = head
    	while fast and fast.next:
    	    fast = fast.next.next
    	    slow = slow.next
    	    if slow == fast:
    	    	return True
    	return False
关于环形链表问题的总结:
  1. 快慢指针一直到相遇时的循环次数等于环的长度。
    两者相遇在慢指针走了一圈时。
    因为slow的速度代表的是链表基本的长度单位,即从一个节点移动到下一个节点的距离。当循环结束时,slow走了1圈,正好是环的长度。
  2. 快慢指针相遇点到环入口的距离=链表起始点到环入口的距离。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值