题解 | #删除链表中重复的结点#

删除链表中重复的结点

http://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef

纯自己思考的结果,花了几个小时,时间和空间消耗的优化超过90%+提交的用户。 我只采用了两个临时的节点。

我的思考是: 一个节点位于重复节点串的前一个节点,另一个节点则是在遍历原始链表 第一个节点的初始化为原始链表的第一个元素,这实际上不能保证它不属于某个连续重复节点串中,但是,它可以在最后被很容易的去除,且不影响之后节点的正确性。

我记录前一个节点的值,并将新节点的值和其比较。因此,在遍历链表的过程中,情况可分为当前节点(即我采用的第二个临时节点)和之前节点的值,相同或不相同两种情况。 我用count参数记录当前节点是否和之前的节点有重复。

第一种情况。如果当前节点和之前的节点的值相同,我们简单的将count加1。不需要改变第一个节点的值。

第二种情况。如果当前节点和之前的节点的值不同。我们需要考虑,当前节点是否为连续相同节点的起点,还是仅仅是普通的不连续的另一个节点。如果是连续节点的起点,则第一个节点不需要动,但是改变count计数从0重新开始。当它是仅仅是普通的不连续的另一个节点,且count数大于0,我们将forenode的next直接连接到当前节点(第二个节点),这就跳过了中间的重复节点。又或者它是仅仅是普通的不连续的另一个节点,且count数等于0。则移动第一个节点,但不需要改变它的next指向,因为不需要跳过连续重复节点。此外,我们的判断总是引用当前节点的next,因此还需要考虑next为None的边界。

class Solution:
    def deleteDuplication(self, pHead: ListNode) -> ListNode:
        # 无节点
        if pHead is None:
            return None
        # 只有一个节点的情况
        elif pHead.next is None:
            return pHead
        # 只有两个节点的情况
        elif pHead.next.next is None:
            if pHead.next.val != pHead.val:
                return pHead
            else:
                return None
        # 三个及以上的节点的情况
        number = pHead.val
        count = 0
        temphead = pHead
        forenode = None

        # 默认选择的第一个forenode节点是否能用,1:能
        if pHead.next.val == pHead.val:
            flag = 0
        else:
            flag = 1

        while temphead is not None:
            # forenode 需要设置为第一个不重复的字符节点上
            # 我的处理是暂时不管,即默认为原始链表的第一个节点
            # 最后,返回新头节点之前,判断一下能不能用(原始链表第一个节点是否重复了)
            # 若不能用,我就从我的新链表的第二个节点开始
            if forenode is None:
                forenode = temphead
                temphead = temphead.next
                continue
            # 第一次遇到不同的字符,要将中间的重复元素去除
            if temphead.val != number:
                # 最后一个元素
                if temphead.next is None:
                    count = 0
                    forenode.next = temphead
                    break
                elif temphead.val != temphead.next.val and count == 0:
                    forenode = temphead
                # 完美的情况,仅一个字符连续相同,即没有多个重复的字符段连在一起
                # 放心的更新节点
                elif temphead.val != temphead.next.val and count > 0:
                    count = 0
                    forenode.next = temphead
                    forenode = temphead
                # 一个字符的连续段后开始新的字符连续段
                # 此时只更新count,number,forenode暂不更新(即便到了最后,因为count!=0,我们的后处理可以
                # 把多个字符重复段一起去除)
                elif temphead.val == temphead.next.val and count > 0:
                    count = 0
                # 碰到了新的字符,无论如何都要更新number
                number = temphead.val
            # 遇到相同的字符
            else:
                count += 1
            temphead = temphead.next

        # 后面的几个字符全部是重复的,或多个连续的重复字符串
        if count > 0:
            forenode.next = None

        if flag == 1:
            return pHead
        else:
            return pHead.next
全部评论

相关推荐

xiaolihuam...:当然还有一种情况是你多次一面挂,并且挂的原因都比较类似,例如每次都是算法题写不出来。面试官给你的评价大概率是算法能力有待加强,算法能力有待提高,基础知识掌握的不错,项目过关,但是coding要加强。短期内高强度面试并且每次都是因为同样的原因挂(这个你自己肯定很清楚),会形成刻板印象,因为你偶尔一次算法写不出来,面试官自己也能理解,因为他清楚的知道自己出去面试也不一定每一次面试算法都能写出来。但是连续几次他发现你的面屏里面都是算法有问题,他就认为这不是运气问题,而是能力问题,这种就是很客观的评价形成了刻白印象,所以你要保证自己。至少不能连续几次面试犯同样的错。算法这个东西比较难保证,但是有些东西是可以的,例如某一轮你挂的时候是因为数据库的索引,这个知识点答的不好,那你就要把数据库整体系统性的复习,下一轮面试你可以,项目打的不好,可以消息队列答的不好,但是绝对不可以数据库再答的不好了。当然事实上对于任何面试都应该这样查漏补缺,只是对于字节来说这个格外重要,有些面试官真的会问之前面试官问过的问题
点赞 评论 收藏
分享
马里奥天生励志:估计是寄了,又是一个测试发现网的
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务