​LeetCode刷题实战86: 分隔链表

程序IT圈

共 2988字,需浏览 6分钟

 ·

2020-11-07 02:17

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 分隔链表,我们先来看题面:

https://leetcode-cn.com/problems/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.

题意


给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

样例

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5



解题

https://www.cnblogs.com/techflow/p/13365497.html

题解

由于问题当中并没有对我们如何处理链表以及当中的元素做出限制,所以我们可以随意操作这个链表以及其中的数据,很容易想到最简单的方法就是我们根据x将链表当中的元素分成两个部分,分别存入两个链表当中,最后再将这两个链表合并在一起。合并的方式也非常简单,只需要将链表连接在一起即可。
这种思路非常无脑,几乎不涉及什么难点,只需要遍历链表然后分别插入不同的链表即可,最后再把这两个链表合并成一个就搞定了。
我们很容易就可以写出代码:

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        # 创建两个链表
        left = ListNode(0)
        right = ListNode(0)
        # 以及用来遍历这两个链表的指针
        ln = left
        rn = right
        pnt = head
        while pnt is not None:
            # 小于x则插入left,否则插入right
            if pnt.val < x:
                ln.next = ListNode(pnt.val)
                ln = ln.next
            else:
                rn.next = ListNode(pnt.val)
                rn = rn.next
            pnt = pnt.next
        
        # 将leftright合并
        ln.next = right.next
        return left.next


这样我们固然做了出来,但是我们是在抛弃原链表的基础上做出来的,毕竟开辟了额外的空间。如果我们想要不创建新的链表来解决这题应该怎么办呢?
其实也是很简单的,我们可以遍历链表,如果发现了大于等于x的元素就将它挪到链表的最后。这样当我们遍历结束的时候,就完成了链表的操作。这个思路虽然简单,但是在实现的时候有很多坑点,需要特别小心。
比如我们需要一个值来记录遍历的重点,因为我们在遍历的时候可能会将一些元素挪到链表的最后。所以我们就不能以None来作为终点了,否则会导致死循环。我们需要以大于等于x的第一个元素作为结束点,当遍历到了这个位置的时候结束。还有很多其他关于链表操作的细节,我们可以来查看代码:


class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        tail = head
        if head is None:
            return None
        
        # 找到结尾,当找到了大于等于x的元素就放入结尾后面
        while tail.next is not None:
            tail = tail.next
            
        # 记录遍历的终点
        end_point = None
        
        pnt = ListNode(0)
        pnt.next = head
        head = pnt

        while pnt.next is not end_point:
            cur = pnt.next
            if cur.val >= x:
                # 插入在末尾
                tail.next = cur
                tail = cur
                # 如果终点是None的话则进行更新
                # end_point只会更新一次
                if end_point is None:
                    end_point = cur
                pnt.next = cur.next
                continue
            pnt = pnt.next
        tail.next = None
        return head.next

总结

在这题当中,我们面临的问题是操作链表,将链表当中的一些元素提取出来放在链表最后。无论我们是自己创建新的链表来满足条件,还是在原链表的基础上进行修改,算法的复杂度都是一样的,只是空间复杂度不同,也因此带来的编码复杂度也不同。相对来说,第一种做法更加简单一些,第二种稍稍复杂,但是也并不难,只要熟悉链表的基本操作,应该都是可以做出来的。
关于链表相关的问题我们应该已经做了不少了,今天的题目算是很基础了,相信大家肯定都没有问题,我也就不再赘述了。

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力。


上期推文:

LeetCode50-80题汇总,速度收藏!
LeetCode刷题实战81:搜索旋转排序数组 II
LeetCode刷题实战82:删除排序链表中的重复元素 II
LeetCode刷题实战83:删除排序链表中的重复元素
LeetCode刷题实战84: 柱状图中最大的矩形

浏览 32
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报