我新建的个人博客,欢迎访问:hmilzy.github.io


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

题目链接: 两两交换链表中的节点

方法一:同样设置虚拟头结点。这里需要操作的结点数很多,数四个分别为 cur、firstNode、secondNode、temp,判断循环结束的条件需要注意一下,避免出现空指针异常

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {

ListNode dummyhead = new ListNode(0);
dummyhead.next = head;
ListNode cur = dummyhead;
ListNode temp;
ListNode firstNode;
ListNode secondNode;

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 dummyhead.next;
}
}

方法二:递归法(此处有点难以理解,需要多画图吧)

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {

//递归法
if(head == null || head.next == null){
return head;
}

ListNode temp = head.next;
ListNode newNode = swapPairs(temp.next);

temp.next = head;
head.next = newNode;

return temp;
}
}

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

题目链接: 删除链表的倒数第 N 个结点

第一个思路:肯定是先遍历链表,得到链表长度。然后重新从头结点开始遍历,找到要删除结点的前一个结点即可。

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {

//第一种做法当然是先遍历链表,找出链表长度。然后再遍历到倒数第n个结点附近,进行删除
ListNode dummyhead = new ListNode(0);
dummyhead.next = head;
ListNode cur = dummyhead;
int size = 0;
while(cur.next != null){
cur = cur.next;
size++;
}

//找到要删除结点的前一个结点
cur = dummyhead;
for(int i = 0; i < size - n; i++){
cur = cur.next;
}
cur.next = cur.next.next;

return dummyhead.next;
}
}

第二个方法:倒数第n个结点,可以从头节点开始,找到一个大小为n的窗口,也就是双指针。
当右指针遍历到链表尾部的时候,左指针就正好是要删除的结点的前一个结点,然后再删除即可。
多画图!!!

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
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {

ListNode dummyhead = new ListNode(0);
dummyhead.next = head;

ListNode fast = dummyhead;
ListNode slow = dummyhead;

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

while(fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;

return dummyhead.next;
}
}

面试题 02.07. 链表相交

题目链接: 链表相交
参考题解:思路十分巧妙

1
2
3
4
5
6
7
8
9
10
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA, B = headB;
while (A != B) {
A = A != null ? A.next : headB;
B = B != null ? B.next : headA;
}
return A;
}
}

142. 环形链表 II

题目链接: 环形链表 II
具体思路可以看卡哥文章,很清晰。

要判断是否成环。这里采用快慢指针的思路,满指针走一步,快指针走两步,看是否会相遇。

成环之后,要返回进入环的位置。可以先找到相遇点位置,让一个指针从头结点开始走,另一个指针从相遇点开始走,最后一定相遇,且相遇的地方就是环入口。

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
46
47
48
49
50
51
52
53
54
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {

ListNode fast = head;
ListNode slow = head;
//找到相遇点
while (true) {
if (fast == null || fast.next == null) return null;
fast = fast.next.next;
slow = slow.next;
if (fast == slow) break;
}
//一个从头结点出发,一个从相遇点出发。总会相遇
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return fast;


/*
ListNode fast = head;
ListNode slow = head;

while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;

if(slow == fast){
ListNode index1 = fast;
ListNode index2 = head;
while(index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
*/
}
}