分类刷题:链表的查找

链表中环的入口结点

https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=265&tqId=39225&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D13&difficulty=undefined&judgeStatus=undefined&tags=&title=

分类刷题的第二天:

JZ23 链表中环的入口结点

思路:

最常规易懂的解法就是遍历整个链表结点,然后用哈希表来存储已访问过的结点,最后进行对比。 若该结点已存在哈希表中,则代表该结点是我们要找的环形链表的入口结点;否则把结点添加到哈希表中,继续往下遍历。

    def EntryNodeOfLoop(self, pHead):
        # write code here
        dict = {}
        i = 0
        while pHead:
            if pHead.val not in dict:
                dict[i] = pHead.val
                pHead = pHead.next
                i += 1
            else:
                return pHead.val

纠正:

  1. 首先第七行用dict[i]=pHead.val其中的i没有实际存在的意义,相当于给遍历到的元素value加上了一个key,所以可以不用dict,只用set来保存value,而不加上key。而且dict的内存比set要大很多,经过修改发现用dict会超过内存。 alt

(补充set和dict的区别:https://www.cnblogs.com/chenwolong/p/dict.html)

  1. 哈希表中增加元素直接用add, nodes.add(pHead)。

按照上述思想对源代码进行改进:

alt

不太明白为什么原来都要node.val而这边说是个int的结构,留一下

继续修改:

    def EntryNodeOfLoop(self, pHead):
        # write code here
        dict = set()
        i = 0
        while pHead:
            if pHead not in dict:
                dict.add(pHead)
                pHead = pHead.next
                i += 1
            else:
                return pHead

复现的时候,没看懂为啥要设置一个毫无作用的i

要注意啊,虽然这次浮现记住了要用set(),但是还是忘记了怎么使用set类似于list里append的功能,要经常去复习add

第一遍复现:

    def EntryNodeOfLoop(self, pHead):
        # write code here
        dict = set()
        while pHead:
            if pHead not in dict:
                dict.add(pHead)
                pHead = pHead.next
            else:
                return pHead

解法2:快慢双指针

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        #创建快、慢两种指针
        fast, slow = pHead, pHead
        while True:
            #第一种结果: fast 指针走过链表末端,说明链表无环,返回 None
            if not fast or not fast.next:
                return None            
            #慢指针一次走一步;快指针一次两步
            slow = slow.next
            fast = fast.next.next
            #如果有环,第一次相遇:
            if slow == fast:
                break
        #第二次相遇,fast回到链表起点位:
        fast = pHead
        #fast、slow两指针不相遇的时候都各走一步:
        while slow != fast:
            fast = fast.next
            slow = slow.next
        #再次相遇即slow所在节点
        return slow 

反正我写不出来

JZ22 链表中倒数最后k个结点

自己的解法:

    def FindKthToTail(self , pHead: ListNode, k: int) -> ListNode:
        # write code here
        def length(pHead):
            count = 0
            while pHead:
                pHead = pHead.next
                count += 1
            return count
        n = length(pHead)
        if k > n:
            return None
        else:
            for _ in range(n-k):
                pHead = pHead.next
            return pHead

注意: 首先,要熟悉length函数的写法,记住count从0开始遍历;

其次要注意直接print pHead就行了,pHead不是一个节点,是一个链表,也就是说后面还有一串。

解法2:快慢指针

    def FindKthToTail(self , pHead: ListNode, k: int) -> ListNode:
        fast = pHead
        slow = pHead
        #快指针先行k步
        for i in range(0,k): 
            if fast != None:
                fast = fast.next
            #达不到k步说明链表过短,没有倒数k
            else: 
                return None
        #快慢指针同步,快指针先到底,慢指针指向倒数第k个
        while fast:
            fast = fast.next
            slow = slow.next
        return slow

全部评论

相关推荐

牛客963010790号:一般是hr拿着老板账号在招人不是真是老板招
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务