代码随想录算法训练营第四天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II

24. 两两交换链表中的节点

题目链接/文章讲解/视频讲解: https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html

//思路 用了虚拟头结点 头位置记录head之前的简单很多 ,然后用自己的思路写了一下 虽然只是变量改了一下,但是一下A了 没毛病

func swapPairs(head *ListNode) *ListNode {
	dummy:=&ListNode{
		Next: head,
	}
	pre:=dummy
	for head!=nil &&head.Next!=nil{
		pre.Next = head.Next
		next:=head.Next.Next
		head.Next.Next = head
		head.Next = next

		pre = head
		head = next
	}

	return dummy.Next

}
func swapPairs(head *ListNode) *ListNode {
	dummy:=&ListNode{
		Next: head,
	}
	first := dummy
	for head!=nil&&head.Next!=nil {
		second := head
		third := head.Next
		next:=head.Next.Next
		first.Next = third
		third.Next = second
		second.Next = next
		first = head
		head = next
		
	}
	return dummy.Next

}

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

题目链接/文章讲解/视频讲解:https://programmercarl.com/0019.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B9.html

思路 基本算自己思路写完的吧,就是快慢指针 先走两步 然后慢的再走 快的走到头慢的刚好到要删除的地方

func removeNthFromEnd(head *ListNode, n int) *ListNode {
	dummy := &ListNode{}
	dummy.Next = head
	cur := dummy
	slow := dummy
	for i:=n;i>=0;i-- {
		if cur==nil{
			return head
		}
		cur = cur.Next
	}
	for cur!=nil {
		slow = slow.Next
		cur = cur.Next
	}
	slow.Next = slow.Next.Next
	return dummy.Next
}

面试题 02.07. 链表相交

题目链接/文章讲解:https://programmercarl.com/%E9%9D%A2%E8%AF%95%E9%A2%9802.07.%E9%93%BE%E8%A1%A8%E7%9B%B8%E4%BA%A4.html

思路:这题自己也能写 就是太丑了 写了三四个for循环 没卡哥这写的优雅

func getIntersectionNode(headA, headB *ListNode) *ListNode {

	sizeA:=0
	sizeB:=0
	curA:=headA
	curB:=headB
	
	for curA!=nil{
		curA= curA.Next
		sizeA++
	}
	for curB!=nil{
		curB= curB.Next
		sizeB++
	}
	var step int
	var slow, fast *ListNode
	
	if sizeA>sizeB{
		step = sizeA-sizeB
		fast,slow= headA,headB
	}else {
		step = sizeB-sizeA
		fast,slow= headB,headA
	}

	for i := 0; i < step; i++ {
		fast = fast.Next
		
	}
	for fast!=slow {
		fast=fast.Next
		slow=slow.Next
		
	}

	return fast
    
}

//双指针

思路:这个写法确实简单,但是不好理解 自己还证了一下才理解

// a b c d a走完接b b走完接a 总路数一样 b d 相等 a+c 和c+a 也相等 必走到相交点

func getIntersectionNode(headA, headB *ListNode) *ListNode {
	l1, l2 := headA, headB
	for l1 != l2 {
		if l1 != nil {
			l1 = l1.Next
		} else {
			l1 = headB
		}
		if l2 != nil {
			l2 = l2.Next
		} else {
			l2 = headA
		}

	}
	return l1
}

142.环形链表II

题目链接/文章讲解/视频讲解:https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html

思路:思路非常清晰,快慢指针 总有相遇的时候 相遇后慢指针和head一起走相遇了就是入口 通过证明 入口前的和慢指针相遇后走的是相同的 所以可以用 for slow!=head判定

func detectCycle(head *ListNode) *ListNode {
	//n(a+b)=a+b+c+b
	//假设n为2
	//a=c  当相遇后 头结点和slow节点都往下走 当相遇的时候就是环形链表的入口
	fast,slow:=head,head
	for fast!=nil&&fast.Next!=nil{
		fast=fast.Next.Next
		slow = slow.Next
		//相遇
		if slow ==fast{
			for slow!=head{
				slow =slow.Next
				head = head.Next
			}
			return head
		}
	}
	return nil
}

总结

第四天了 算这一周结束了 ,第三刷总体感觉 哎 很爽 起码大部分题自己能做个7788了 思路也有了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值