24.两两交换链表中的节点
题目链接:力扣
重点还是虚拟节点的运用,看图理解很容易:
解题代码:
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode();
dummy.next = head;
ListNode cur = dummy;
while (cur.next != null && cur.next.next != null) {
ListNode temp = cur.next.next.next;
ListNode first = cur.next;
ListNode second = cur.next.next;
cur.next = second;
second.next = first;
first.next = temp;
cur = first;
}
return dummy.next;
}
19.删除链表的倒数第 N 个节点
题目链接:力扣
重点是快慢指针,首先让快指针移动 N 次,然后慢指针再开始移动,之道快指针 null 的时候,慢指针所处的位置就是倒数第 N 个节点。但是我们需要删除这个节点,所以我们需要获得删除节点的前一个节点,所以快指针要移动 N+1 次。
我这里是写在一个 for 循环中,用变量 i 递增来判断慢指针是否可以移动了。还可以先用一个 for 循环 n 次,让快指针先到达,然后再用一个 while 让快慢指针一起前进:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode();
dummy.next = head;
ListNode fast = dummy;
ListNode indexPreNode = dummy;
// 这里是寻找倒数第 n+1 个节点,所以i=0,这样快指针会多执行一步,慢指针才会开始执行
int i = 0;
while (fast != null) {
fast = fast.next;
if (i > n) {
indexPreNode = indexPreNode.next;
}
i++;
}
indexPreNode.next = indexPreNode.next.next;
return dummy.next;
}
面试题 02.07. 链表相交
题目链接:力扣
这道题我首先尝试了暴力解法,两个for循环遍历链表,相同就返回,然后看了下代码随想录的解法。
思路很明确:如果是节点相交,那么后面的长度一定一致,所以我们首先计算出每个连表的长度,然后把长链表的坐标移动到给短链表长度一致的地方,之后只需要一个循环,长链表和短链表同时向前遍历,判断相同时就可以直接返回。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode currA = headA, currB = headB;
int lenA = 0, lenB = 0;
while (currA != null) {
currA = currA.next;
lenA++;
}
while (currB != null) {
currB = currB.next;
lenB++;
}
currA = headA;
currB = headB;
// 注意做一个替换操作,让currA始终表示长列表
if (lenB > lenA) {
int tempLen = lenA;
lenA = lenB;
lenB = tempLen;
ListNode tempNode = currA;
currA = currB;
currB = tempNode;
}
int dif = lenA - lenB;
while (dif-- > 0) {
currA = currA.next;
}
while (currA != null) {
if (currA == currB) {
return currA;
}
currA = currA.next;
currB = currB.next;
}
return null;
}
142.环形链表 II
题目链接:力扣
如果不看代码随想录,自己永远想不出来解法系列:代码随想录-环形列表解析
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
int x = 0;
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;
}
简单点可以直接用哈希表,下面再贴个哈希表的
public ListNode detectCycle(ListNode head) {
HashSet hashSet = new HashSet();
ListNode cur = head;
while (cur != null) {
if (hashSet.contains(cur)) {
return cur;
}
hashSet.add(cur);
cur = cur.next;
}
return null;
}
总结
今天四道题压力满满,花了5个多小时来学习,这还是极大克制了自己思考的时间,想不出果断看解析的情况下。还是需要改进下学习节奏,这个样子忙起来就会跟不上进度的。