代码随想录第四天

24 两两交换链表中的节点

https://leetcode.com/problems/swap-nodes-in-pairs/description/

正常模拟交换过程

首先建立dummy节点,之后设置第一节点,第二节点,temp
while 判断是否有两个节点可以交换

模拟过程:
存储cur的第三个节点
存储cur的第二个节点
存储cur的第一个节点

cur的next是第二个节点
第二个节点的next是第一个节点
第一个节点的next是第三个节点
之后cur移到第一个节点的位置(即新虚拟节点的位置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution{
public ListNode swapPairs(ListNode head){
ListNode temp;
ListNode firstNode;
ListNode secondNode;
ListNode dummy = new ListNode(-1, head);
ListNode cur = dummy;

while (cur.next != null && cur.next.next != null){
temp = cur.next.next.next;
firstNode = cur.next;
secondNode = cur.next.next;

cur.next = secondNode;
secondNode.next = firstNode;
firstNode.next = temp;

cur = firstNode;

}

return dummy.next;
}


}

递归方法: 类似翻转链表中反向递归方法(需要研究)不是很明白

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution{
public ListNode swapPairs(ListNode head){
if (head == null || head.next == null) return head;
ListNode next = head.next;
ListNode newNode = swapPairs(next.next);
next.next = head;
head.next = newNode;

return next;

}

}

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

https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/

自己可以写出两次遍历的解法:
第一次找到size
第二次把节点删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution{
public ListNode removeNthFromEnd(ListNode head, int n){
ListNode dummy = new ListNode(-1,head);
ListNode pre = dummy;
ListNode cur = head;
int size = 0;
while (cur != null){
cur = cur.next;
size++;
}

for (int i = 0; i < size - n; i++){
pre = pre.next;
}

pre.next = pre.next.next;

return dummy.next;
}

}

快慢指针经典题目

设置双指针,快指针先走n步,后快指针和慢指针一起走到快指针的链表尽头,此时删除慢指针所指node

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution{
public ListNode removeNthFromEnd(ListNode head, int n){
ListNode dummy = new ListNode(-1, head);

ListNode fastNode = dummy;
ListNode slowNode = dummy;

for (int i = 0; i <= n; i++){
fastNode = fastNode.next;
}

while (fastNode != null){
fastNode = fastNode.next;
slowNode = slowNode.next;
}
slowNode.next = slowNode.next.next;
return dummy.next;

}

}

160 链表相交

https://leetcode.com/problems/intersection-of-two-linked-lists/description/
求两链表交点节点的指针
首先求出两链表的长度
把两个链表的尾部对齐,即把长链表的指针指到和短链表相同长度
如果指针数值相同则相交,否则向后移动指到null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Solution{
public ListNode getIntersectionNode(ListNode headA, ListNode headB){
ListNode curA = headA;
ListNode curB = headB;

int sizeA = 0;
int sizeB = 0;

while (curA != null){
curA = curA.next;
sizeA++;
}

while (curB != null){
curB = curB.next;
sizeB++;
}

curA = headA;
curB = headB;

if (sizeA < sizeB){
for (int i = 0; i < sizeB-sizeA; i++){
curB = curB.next;
}
} else if (sizeA > sizeB){
for (int i = 0; i < sizeA-sizeB; i++){
curA = curA.next;
}
}

while (curA != null){
if(curA == curB){
return curA;
} else {
curA = curA.next;
curB = curB.next;
}

}
return null;
}

}

142 环形链表II

https://leetcode.com/problems/linked-list-cycle-ii/description/

判断链表内是否有环:
可通过快慢指针来判断,快走两步,慢走一步,这样如果两指针相遇,则链表内定存在环

如果有环如何判断环入口:
通过公式化简可得:
如果快指针走过一圈后就遇到慢指针,则从遇到的点开始和头节点同时走相同步数,两指针相遇的点即为入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution{
public ListNode detectCycle(ListNode head){
ListNode slowIndex = head;
ListNode fastIndex = head;

while (fastIndex != null && fastIndex.next != null){
slowIndex = slowIndex.next;
fastIndex = fastIndex.next.next;

if (slowIndex == fastIndex){
ListNode index1 = slowIndex;
ListNode index2 = head;

while (index1 != index2){
index1 = index1.next;
index2 = index2.next;
}

return index1;
}
}

return null;
}
}