数据结构与算法专题汇总(三)链表相关leetcode题目(链表反转,链表合并,快慢指针的用法:找中间结点,环的检测,回文判断,删除倒数第n个结点)

本文深入解析了链表数据结构的六大核心算法,包括链表反转、链表合并、寻找中间节点、环检测、回文判断及删除倒数第n个节点。通过详细的代码示例和算法步骤,帮助读者掌握链表操作的关键技巧。
1.链表反转leetcode206

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

链表反转就是将结点的pre赋值给当前结点的next的过程,其中注意不要丢失指针

class ListNode:
    def __init__(self,x):
        self.val = x
        self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
    	cur = head
    	pre = None

		while(cur):
			nxt = cur.next
			cur.next = pre
			pre = cur
			cur = nxt
		return pre
   	
   		
递归法
func reverseList(head *ListNode) *ListNode {
    if head.Next == nil || head == nil{
        return head
    }
    cur := reverseList(head.Next)
    head.Next.Next = head
    head.Next = nil
    return cur 
}
2.链表合并leetcode21

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class ListNode:
    def __init__(self,x):
        self.val = x
        self.next = None

class Solution:
#方法一,比较了l1和l2的各个结点,分别加入l3
#注意为空的条件
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
    	p1 = l1
    	p2 = l2
    	l3 = ListNode(-1)
    	p3 = l3

		while p1 and p2:
			if p1.val <= p2.val:
				p3.next = p1
				p1 = p1.next
			else:
				p3.n3xt = p2
				p2 = p2.next
			
			p3 = p3.next
		
		p3.next = p1 if p1 is not None else p2
		#注意返回的是l3.next
		return l3.next

#方法2,递归
    def mergeTwoLists2(self, l1: ListNode, l2: ListNode) -> ListNode:
    	if not l1:
    		return l2
		if not l2:
			return l1

		if l1.val <= l2.val:
			l1.next = self.mergeTwoLists2(l1.next,l2)
			return l1
		else:
			l2.next = self.mergeTwoLists2(l1,l2.next)
			return l2
		
快慢指针
3.找中间结点leetcode876

给定一个带有头结点 head 的非空单链表,返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。
示例 1:

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class ListNode:
    def __init__(self,x):
        self.val = x
        self.next = None

class Solution:
    def middleNode(self, head: ListNode) -> ListNode:
	    	slow = fast = head
			
			while fast and fast.next:
				slow = slow.next
				fast = fast.next.next
			
			return slow

4.环的检测leetcode141

给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

class ListNode:
    def __init__(self,x):
        self.val = x
        self.next = None

class Solution:
#快慢指针
    def hasCycle(self, head: ListNode) -> bool:
    	slow = fast = head
		
		while fast and fast.next:
			slow = slow.next
			fast = fast.next.next

			if slow == fast:
				return True
		
		return False
# 集合方式
    def hasCycle2(self, head: ListNode) -> bool:
    	a = {}
		while head:
			if head in a:
				return True
			a[head] = -1
			head = head.next
		return false


5.回文判断leetcode面试题 02.06

编写一个函数,检查输入的链表是否是回文的。
示例 1:
输入: 1->2
输出: false

示例 2:
输入: 1->2->2->1
输出: true

class ListNode:
    def __init__(self,x):
        self.val = x
        self.next = None

class Solution:
	    def isPalindrome(self,headNode:ListNode) -> bool:
	    	slow = fast = p = headNode
			
			while fast and fast.next:
				slow = slow.next
				fast = fast.next.next
	
		#找中间结点,将中间结点之后的部分倒转,再与之前的部分判断是否相等
			rp = self. reverseList(slow)
			
			while rp:
				if rp.val != p.val:
					return False
				rp = rp.next
				p = p.next
			
			return True
		
		

		 def reverseList(self, head: ListNode) -> ListNode:
		    	cur = head
		    	pre = None
		
				while(cur):
					nxt = cur.next
					cur.next = pre
					pre = cur
					cur = nxt
				return pre		

6.删除倒数第n个结点leetcode19

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

class ListNode:
    def __init__(self,x):
        self.val = x
        self.next = None

class Solution:
#这里快指针比慢指针多走n步,慢指针指向的则为倒数第n个结点
#为了方便删除,这里返回的慢指针指向被删结点的前驱结点
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
	    	slow = fast = head

			for i in range(n):
				fast = fast.next
			
			#若快指针为空,则表示需要删除的是头结点
			if not fast:
				return head.next

			while fast.next:
				fast = fast.next
				slow = slow.next
			
			slow.next = slow.next.next
			return head
					    	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值