问题一:
面试题 02.07. 链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
输入 | 输出 |
intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 | 输出:Intersected at '8' 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0) |
思路:遍历求指针长度,根据长度较长的链表先移动,等到两者平齐再同步移动,求是否有相遇。
方法2:相同思想,但是两个指针遍历两个数组
方法3:哈希表
代码:
//
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
lenA:= 0
lenB:= 0
curA:= headA
curB:= headB
for curA!=nil{curA = curA.Next;lenA++}
for curB!=nil{curB = curB.Next;lenB++}
step:=0
var fast, slow *ListNode
if lenA >lenB{
step= lenA -lenB
fast,slow=headA,headB
}
if lenB >=lenA{
step= lenB -lenA
fast,slow=headB,headA
}
for i:=0; i < step; i++{
fast =fast.Next
}
for fast!=slow{
fast =fast.Next
slow =slow.Next
}
return fast
}
func getIntersectionNode(headA, headB *ListNode) *ListNode {
if headA == nil || headB == nil {
return nil
}
pa, pb := headA, headB
for pa != pb {
if pa == nil {
pa = headB
} else {
pa = pa.Next
}
if pb == nil {
pb = headA
} else {
pb = pb.Next
}
}
return pa
}
func swapPairs(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
newHead := head.Next
head.Next = swapPairs(newHead.Next)
newHead.Next = head
return newHead
}
问题二:
19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
输入 | 输出 |
head = [1,2,3,4,5], n = 2 | [1,2,3,5] |
head = [1], n = 1 | [] |
思路:没啥好说的双指针,记得从dummy开始
代码:
//
func removeNthFromEnd(head *ListNode, n int) *ListNode {
if head == nil || head.Next ==nil{
return nil
}
dummy:=&ListNode{Next:head}
fast,slow:= dummy,dummy
for i:=0;i<n+1;i++{fast = fast.Next}
// fast = fast.Next
for {
if fast ==nil{
slow.Next = slow.Next.Next
break
}
fast = fast.Next
slow = slow.Next
}
return dummy.Next
}
问题三:
24. 两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
输入 | 输出 |
head = [1,2,3,4] | [2,1,4,3] |
head = [] | [] |
思路:反转链表很像,但是这个需要指针往后推
代码:
//
func swapPairs(head *ListNode) *ListNode {
dummy:= &ListNode{Next:head}
pre:= dummy
cur:=head
for cur!=nil && cur.Next!=nil {
pre.Next = cur.Next
tem :=cur.Next.Next
cur.Next.Next = cur
cur.Next=tem
pre = cur
cur = tem
}
return dummy.Next
}
问题四:
141. 环形链表
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
输入 | 输出 |
head = [3,2,0,-4], pos = 1 | true |
head = [1,2], pos = 0 | true |
代码
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func hasCycle(head *ListNode) bool {
if head == nil || head.Next ==nil{
return false
}
pre:=head
next:= head.Next
for pre!= next {
if next.Next == nil || next.Next.Next ==nil{ return false}
pre = pre.Next
next =next.Next.Next
}
return true
}
问题四:
142. 环形链表 II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
输入 | 输出 |
head = [3,2,0,-4], pos = 1 | 输出:返回索引为 1 的链表节点 |
输入:head = [1,2], pos = 0 | 输出:返回索引为 0 的链表节点 |
func detectCycle(head *ListNode) *ListNode {
slow,fast := head,head
for fast!=nil && fast.Next!=nil{
slow =slow.Next
fast = fast.Next.Next
if slow == fast{
for slow !=head{
slow = slow.Next
head = head.Next
}
return head
}
}
return nil
}