明天周末啦~~~
LeetCode 24. 两两交换链表中的节点
LeetCode 19.删除链表的倒数第N个节点
LeetCode 面试题 02.07. 链表相交
LeetCode 142.环形链表II
多设几个变量,整个循环,你就换吧,一换一个不吱声。
/**
* 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;
}
}
首先删除操作没问题,其次要求使用一趟扫描实现,首先想到双指针。
怎样找到哪个是倒数第 N 个节点呢?
让快指针先走 N 个,快慢指针再一起走就能找到要删除的节点了。
但是需要获取删除节点的前一个节点,因此可以让快指针先走 N+1 个。
fast == null 的时候结束返回就好了。
/**
* 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; }
* }
*/
// 进阶:你能尝试使用一趟扫描实现吗?
// 双指针 fast slow fast 先走 n 步, 在让他俩同时走,直到 fast 走到最后, 删除slow
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyhead = new ListNode(0);
dummyhead.next = head;
ListNode fast = dummyhead;
ListNode slow = dummyhead;
// fast首先走n + 1步
for (int i = 0; i <= n; i++) {
fast = fast.next;
}
// 结束时 fast == null, 因此要找到删除点的前一个节点
// 需要在上面让 fast 多走一步
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyhead.next;
}
}
同上一样,双指针,先求 A B 长度, 求长度之差,让长的链表指针先走,对齐,到距离最末同样长度的位置处开始遍历,如果两个节点相同,就返回。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int m = 0, n = 0;
while (curA != null) {
m++;
curA = curA.next;
}
while (curB != null) {
n++;
curB = curB.next;
}
curA = headA;
curB = headB;
if (n > m) {
int tempLen = m;
m = n;
n = tempLen;
ListNode tempNode = curA;
curA = curB;
curB = tempNode;
}
int gap = m - n;
while (gap > 0) {
curA = curA.next;
gap--;
}
while (curA != null) {
if (curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
?
真真正正的快慢指针。快指针每步走2,慢指针每步走1。如果有环,则一定在环内处相逢。
对于环的起始位置,需要列几个式子算一下。
/**
* 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 slow = head;
ListNode fast = 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;
}
}
动动笔吧,你脑子想不出来的话…