10.代码随想录-链表(下)

本文介绍了如何在LeetCode中解决链表相关问题,包括删除链表的倒数第N个节点、寻找两个链表的相交点以及检测环形链表。使用双指针技巧和虚拟头结点简化了问题处理。
摘要由CSDN通过智能技术生成

删除链表的倒数第N个节点

        题干:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

        测试地址:. - 力扣(LeetCode)

         双指针:快指针先走个n步,然后两个指针一起走,快指针走到末尾了,这个时候慢指针也就到了倒数的第n个节点了。比如倒数第一个,那就fast走到fast.next是nil的时候,慢指针就在倒数第二个,那就让slow.next=slow.next.next就可以了

func removeNthFromEnd(head *ListNode, n int) *ListNode {
	dummyhead := &ListNode{
		Val:  0,
		Next: head,
	}
	var fast, slow *ListNode
	fast, slow = dummyhead, dummyhead
	for i := 0; i < n; i++ {
		fast = fast.Next
	}
	for fast.Next != nil {
		fast = fast.Next
		slow = slow.Next
	}
	slow.Next = slow.Next.Next
	return dummyhead.Next
}

链表相交

        题干:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

        测试地址:. - 力扣(LeetCode)

        核心在于如果相交,那么就是从某个节点开始两个节点后面的节点全部相等,也就意味两个链表是尾对齐的,而两个链表差值的地方一定不是相交的。所以忽略两个链表长度差的部分,从相等的部分往后遍历即可。

func getIntersectionNode(headA, headB *ListNode) *ListNode {
    if headA == nil || headB==nil{
        return nil
    }
	var cura, curb = headA, headB
	var lenA, lenB int
	for cura.Next != nil || curb.Next != nil {
		if cura.Next != nil {
			cura = cura.Next
			lenA++
		}
		if curb.Next != nil {
			curb = curb.Next
			lenB++
		}
	}
	var Difference = lenA - lenB
	if Difference > 0 {
		for i := 0; i < Difference; i++ {
			headA = headA.Next
		}
	} else {
		for i := 0; i < (-Difference); i++ {
			headB = headB.Next
		}
	}
	for headA != nil && headB != nil {
		if headA == headB {
			return headA
		}
		headA = headA.Next
		headB = headB.Next
	}
	return nil
}

环形链表II

        题干:给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

        测试地址:. - 力扣(LeetCode)

        推理过程可以看原文:代码随想录

        不过一张图就可以了,背着算了

func detectCycle(head *ListNode) *ListNode {
	fast, slow := head, head
	for fast != nil && fast.Next != nil {
		fast = fast.Next.Next
		slow = slow.Next
		if fast == slow { //有环
			fast = head
			for fast != slow {
				fast = fast.Next
				slow = slow.Next
			}
			return fast
		}
	}
	return nil
}

链表总结

        善用虚拟头结点,可以少考虑要改变首节点的情况。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值