刷题--11/17

学习内容:

为了更有条理地学习,我对每个知识点进行巩固练习,今天做了三道简单的链表题目
1、 合并两个有序链表
2、 两个链表的公共点
3、 判断链表中是否有环


一、 合并两个有序链表

	问题:将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的。

第一次没读懂题目,以为是将链表的同一个位置合并在一块不用排序,看了用例后就理解了。

分析过程:
合并两个链表的思路很直观,首先用一个新链表来作为两个链表合并后的容器,我们很自然地需要为新链表找一个链表头,因此选取两个 h e a d head head中较小的即可。接下来, h e a d . n e x t head.next head.next我们需要比较两个链表当前位置节点的大小,并将更小的放在新链表中并依次类推直到其中一个链表中的所有节点都放在新链表中,最后一个利用有序链表的性质,我们只需要把剩余链表中的节点依次添加在新链表即可。

代码

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
 
#两个链表都是有序链表  首先不断查找较小的节点然后并放在新的链表中
#直到其中一个链表 到达末尾 把另一个拼上去
class Solution:
    def mergeTwoLists(self , l1 , l2 ):
    	#对简单情况的分析
    	if l1==None and l2==None:
    		return None
    	if l1 !=None and l2==None:
    		return l1
    	if l1 ==None and l2!=None:
    		return l2
    	#设置新的链表头
    	newhead = None
    	if l1.val < l2.val:
    		newhead = l1
    		l1 = l1.next
    	else:
    		newhead = l2
    		l2 = l2.next
    	
    	#添加接下来的节点
    	flag = newhead  ###flag 存储了每一步的变化 
    	while l1!=None and l2!=None:
    		if l1.val<l2.val:
    			flag.next = l1
    			l1 = l1.next
    			flag = flag.next
    		else:
    			flag.next = l2
    			l2 = l2.next
    			flag = flag.next
    	#当一个链表添加完成后 将另一个剩余的添加进来
    	while l1!=None:
    		    flag.next = l1
    			l1 = l1.next
    			flag = flag.next
    	while l2!=None:
    		    flag.next = l2
    			l2 = l2.next
    			flag = flag.next
    	return newhead
    			

二、两个链表的公共点

	问题:输入两个链表,找出它们的第一个公共结点。

思路1:首先我们要知道什么是公共节点,两个链表从某一节点开始,他们的next都指向同一个节点。但由于是单向链表的节点,每个节点只有一个next,因此从第一个公共节点开始,之后他们的所有节点都是重合的,不可能再出现分叉。所以可以先遍历两个链表得到他们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个结点。在第二次遍历的时候,在较长的链表上先走若干步,接着同时在两个链表上遍历,找到的第一个相同的结点就是他们的第一个公共结点。时间复杂度为O(m+n),而暴力破解法的时间复杂度为O(mn)。
思路2:其实遍历两个链表也不是不可的,对于 L i n k 1 Link1 Link1 L i n k 2 Link2 Link2,从 L i n k 1 Link1 Link1中取一个节点,然后依次在 L i n k 2 Link2 Link2中查找即可。 O ( m n ) O(mn) O(mn)
思路3:双指针,时间复杂度 O ( m + n ) O(m+n) O(m+n)
在这里插入图片描述
推荐第一和第三种方法

代码

class Solution:
    def FindFirstCommonNode(self , pHead1 , pHead2 ):
        #首先便利两个链表  得到链表的长度
        p1,p2 = pHead1,pHead2
        length1,length2 = 0,0
        while p1!=None:
        	length1 = length1+1
        	p1 = p1.next
        while p2!=None:
        	length2 = length2+1
        	p2 = p2.next
        #找出更长的链表 并且我们都用pHead1来表示
        if length1<length2:
        	pHead1,pHead2 = pHead2,pHead1
        distance = abs(length1-length2)
        for i in range(distance):
        	pHead1 = pHead1.next
        while pHead1!=None and pHead2!=None and pHead1.val !=pHead2.val:
        	pHead1 = pHead1.next
        	pHead2= pHead2.next
        return pHead1
        

看了双指针之后,觉得自己的第一种和第二种方法不太行
https://blog.csdn.net/qq_36243414/article/details/90452723

class Solution:
    def FindFirstCommonNode(self , pHead1 , pHead2 ):
        if pHead1== None or pHead2==None:
        	return None
        else:
        	p1,p2 =pHead1,pHead2
        	while p1 != p2:
	            p1 = p1.next if p1 != None else pHead2
	            p2 = p2.next if p2 != None else pHead1
       		return p1
#好牛啊 简洁明了

三、 判断链表中是否有环

对于这道题,我们同样可以利用双指针来进行解决。快指针快点走,慢指针慢点走,如果链表中有环的话,两者总会在某处相遇;不含环的话,快指针会最先达到None,结束判断。

代码

class ListNode:
    def __init__(self,item):
        self.val = item
        self.next = None
         
class Solution:
  def hasCycle(self , head ):
  	fast,slow = head,head
  	while fast!=None and fast.next!=None:
  		fast = fast.next.next
  		slow=slow.next
  		if fast==slow:
  			return True
  	return False
 
#还有一种方法我不甚理解  等搞懂了 在写解释

```python
class Solution:
    def hasCycle(self , head ):
        # write code here
        # head始终没有变
        cur = head
        while cur:
            cur_next = cur.next
            if cur_next is head:
                return True
            cur.next = head
            cur = cur_next
        return False

坚持坚持
科研去了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值