1.3 python数据结构之链表——链表右移/链表分割/链表逆序

都是一些LeetCode上关于链表的题目,多刷一些这样的题目有助于我们全面熟悉链表那一套理论方法。

题目1.  61. Rotate List (将链表右移K个位置)

Given a list, rotate the list to the right by k places, where k is non-negative.
Example:
Given 1->2->3->4->5->NULL and k = 2,

return 4->5->1->2->3->NULL.

题目解析:

找倒数第k个结点类似,先获取长度最关键,要注意对k>=长度的处理。关键点在于利用三个结点:head(链表头),p(链表尾),q(倒数第k结点的前一个),将三者按顺序连起来即可。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def rotateRight(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        
        if head == None:
            return None
        length = 1
        p = head 
        while p.next:
            p = p.next
            length += 1
        if k == length:
            return head
        elif k > length:
            k = k%length
        cn = 1
        q = head
        while cn < (length-k):
            q = q.next
            cn += 1
        p.next = head
        newhead = q.next
        q.next = None
        return newhead

题目2.  86. Partition List(链表分割)

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.You should preserve the original relative order of the nodes in each of the two partitions.

For example,
Given 1->4->3->2->5->2 and x = 3,

return 1->2->2->4->3->5.

题目解析:

很难想到这题正确的解题思路,开始想象着找到分割的位置,然后将分割点两侧不应在这一组的结点"交换"。错就错在交换了,首先,链表的结点交换是操作中最复杂的操作,详细的可见鄙人所做的py的链表实现;其次,交换破坏了原始相对位置。这一思路可以改良为,将分割点左侧大于等于x的结点插入到分割点右侧(依次),将右侧小于x的插入到分割点左侧(这一步实现可能比较费劲)。

于是看了他人的思路,代码如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def partition(self, head, x):
        """
        :type head: ListNode
        :type x: int
        :rtype: ListNode
        """
        if head == None:
            return head
        p1 = ListNode(-1)
        p2 = ListNode(-1)
        h1, h2 = p1, p2
        while head:
            if head.val <x:
                p1.next = head
                p1 = p1.next
            else:
                p2.next = head
                p2 = p2.next
            head = head.next
        p2.next = None
        p1.next = h2.next
        return h1.next

申请两个头指针,只遍历一遍链表,将两类结点各自挑出来依次连接,最后再合并,实在是简洁高效!时间复杂度O(n),空间复杂度O(1)。还是要领会这一思想。

思考:这一问题实际上说明,快速排序对于单链表存储结构仍然适用,所给的x其实是快排中的主元。(不懂快排的可自行学习,或者等待鄙人慢慢更新博客0 0)

题目3.  92. Reverse Linked List II(链表逆序)

Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,
return 1->4->3->2->5->NULL.

Note:    Given m, n satisfy the following condition:    1 ≤ m ≤ n ≤ length of list.

题目解析:

这是链表逆转操作的加强版,在基本功的逆序操作的基础上,将逆转后的链表头尾再连接到应该连接的地方。代码如下:

class Solution:
    def reverseBetween(self, head, m, n):
        """
        :type head: ListNode
        :type m: int
        :type n: int
        :rtype: ListNode
        """
        if head == None:
            return head
        elif m == n:
            return head
        new = ListNode(-1)
        new.next = head
        head = new
        
        p = head       
        pre = head
        for i in range(m):
            pre = p
            p = p.next
        q = p
        for i in range(n-m):
            q = q.next

        # reverse
        pre_p = q.next
        cur = p
        for i in range(n-m+1):
            h = cur
            tmp = cur.next
            cur.next = pre_p
            pre_p = cur
            cur = tmp            
        pre.next = q        
        return head.next
        

注意的地方有:1,当m=1时比较麻烦,所以一般涉及到链表头的改变的问题,可以在头部之前建一结点,这样可将问题一般化处理;2,特殊情况还有m=n时;3,注意这几个结点的作用,pre 是m点之前的点,p(cur)是m点,q是n点,pre_p即q.next是m-n逆转后尾部需要连接的地方(在其他的逆转问题中一般用None)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值