刷题记录--11/18

学习内容:

今天下雨了,下午在寝室偷懒了一个小时,博客总结差点鸽了。今天做了四道链表,两道简单两道中等。稍微感觉找到了一些套路—合理地使用双指针。明天准备复习总结一下这几天的知识,不求速度但求掌握,另外还要整理下小论文实验数据,明天鸽了(手动狗头)。
1、 给一个链表和一个数字n,输出链表的倒数第n个数
2、 删除链表中重复节点的多余节点
3、 删除链表中重复节点
4、寻找链表中环的入口


一、给一个链表和一个数字n,输出链表的倒数第n个数

	问题:输入一个链表,输出该链表中倒数第k个结点

简单分析一下:这道题的思路很直观,其实就是把链表反序然后输出第 n n n个节点;不考虑return的要求的话,我们也可以借助队列的入列操作即可;
不过下面两种方法掌握起来还是更好一些:
1.加减法:首先遍历链表得到总长度 l e n g t h length length,输出倒数第 n n n个,那么就是正数 l e n g t h + 1 − n length+1-n length+1n个,即 l e n g t h + 1 = n + P o s length+1=n+Pos length+1=n+Pos
2.双指针: n n n可以理解为目标节点与链表尾部之间有 n n n个指针,所以我们可以设置两个指针,其中一个放在头部,另外一个和它间隔 n n n个指针,然后向后查找逐步直到后一个指针指向尾部。
两种方法都写一下
另外就是注意细节优化一下,比如k超过链表长度时,k=0时

代码

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
 #1
class Solution1:
    def FindKthToTail(self, head, k):
        cur = head
        length = 0
        while cur:
            length = length + 1
            cur = cur.next

        if length < k or k == 0:
            return None
        else:
            target = None
            for i in range(length + 1 - k):
                while head:
                    target = head
                    head = head.next
        return target
#2
class Solution:
    def FindKthToTail(self, head, k):
        if head == None:
            return None
        else:
            fast,slow = head,head
            for i in range(k):
                if not fast:
                    return None
                fast=fast.next
            while fast!=None:
                slow = slow.next
                fast = fast.next
            return slow

二、删除问题

我们先看一下两道问题,细品下
在这里插入图片描述
在这里插入图片描述
其实不同之处就是在于保留不保留重复的节点,两个问题都可以用双指针解决。设置两个指针 p r e , c u r pre,cur pre,cur在遍历一次链表的过程中,要做的就是比较前后两个节点,如果值相等固定 p r e pre pre c u r cur cur往后移一个;否则,两个指针都往后移动一步。

代码

class ListNode:
    def __init__(self, val):
        self.val = val
        self.next = None
 
class Solution:
    def deleteDuplicates(self , head ):
    	if head==None or head.next==None:
    		return None
    	else:
    		pre,cur = head,head
    		while pre and cur:
				if pre.val==cur.vall:
					pre.next = cur.next
				else:
					pre = pre.next
				cur = cur.next
			return head

class Solution1:
    def deleteDuplicates(self , head ):
    	Trick=ListNode(0)  #这是一个处理头部节点重复时的技巧
    	Trick.next = head
    	cur = Trick
    	while cur.next and cur.next.next:
    		p1,p2 = cur.next and cur.next.next
    		if p1.val!=p2.val:
    			cur = cur.next
    		else:
    			while p2 and p1.val==p2.val:
    				p2 = p2.next
    			cur.next = p2
		return Trick.next

    			
    	
				
					        

三、链表中的环–环入口点

双指针,双指针,双指针
我们先看一张图
在这里插入图片描述
判断链表中是否有环的快慢指针方法,说的实际一点就是操场跑圈,跑的快的会在环的某处追上慢的。看一下上面的图:最初快慢指针都在X处,快指针跑两步,慢指针跑一步,经过一段时间后,两者第一次在Z又遇见了,这时候我们让快指针从Z点之后都跑一步,让慢指针从X从头跑,两者下一次就会在环入口点遇见。
推导一下:第一次在Z点遇见时,很显然快指针走的路程是慢指针的两倍,可以列式子:2*(a+b)=a+(b+c)*n+b,推出a=(n-1)b+nc=(n-1)(b+c)+c; 接下来,慢指针跑了a到达Y,慢指针跑了c到达Y,相遇。

代码

class Solution:
    def detectCycle(self , head ):
        # write code here
        fast = head
        slow = head
        while fast:
            if fast.next:
                fast = fast.next.next
                slow = slow.next
                if fast == slow:
                    break
            else:
                return None
          
        if not fast:
            return None
          
        fast = head
        while fast != slow:
            fast = fast.next
            slow = slow.next
        return fast

坚持坚持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值