24. 两两交换链表中的节点
本题并没有什么特别的算法技巧,主要考察链表断链和重新链接,直接想的话会有些绕,使用虚拟头节点并且画图更好理解:
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) return head;
ListNode dummyHead = new ListNode(0,head);
ListNode prev = dummyHead;
while(prev.next != null && prev.next.next != null)
{
ListNode cur = prev.next;
ListNode next = cur.next;
//交换
cur.next = next.next;
next.next = cur;
prev.next = next;
prev = cur;
}
return dummyHead.next;
}
}
19.删除链表的倒数第N个节点
这道题是双指针在链表中的应用,想要找到倒数第n个节点,那么可以先让fast指针先走n步(从1计步),再与slow指针一起走,当fast到达末尾,则slow指向的就是倒数第n个节点。但是要注意的是,要执行链表的删除操作,需要找到待删除的节点的前一个节点,即走n+1步(从1计步)。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(-1, head);
ListNode slow = dummyHead;
ListNode fast = dummyHead;
while(n >= 0)
{
fast = fast.next;
n--;
}
while(fast != null)
{
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyHead.next;
}
}
面试题 02.07. 链表相交
这道题迷惑的点在于输入案例有一点难理解,但是只看题目就行。它本质不难,是找两个链表的公共节点。我们找到解决方法的关键在于,如果能把两个链表从尾部对其,那么公共节点就一目了然。而要实现这一步,我们可以让长链表先走n步(两链表的差值),再一起遍历,那么就相当于对其了。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0;
int lenB = 0;
while(curA != null)
{
curA = curA.next;
lenA++;
}
while(curB != null)
{
curB = curB.next;
lenB++;
}
//遍历后归位
curA = headA;
curB = headB;
int diff = 0;
//判断哪个链表更长,就先走。
if(lenA > lenB)
{
diff = lenA - lenB;
while(diff-- > 0)
{
curA = curA.next;
}
}
else
{
diff = lenB - lenA;
while(diff-- > 0)
{
curB = curB.next;
}
}
//同时移动
while(curA != null )
{
if(curA == curB)
{
return curA;
}
else
{
curA = curA.next;
curB = curB.next;
}
}
return null;
}
}
反思
这道题最开始思路不清晰,虽然知道长链表要先走差值步数,但是在写代码的时候忽略了,要判断哪条链表更长。不过,按照代码随想录的思想,其实可以多做一次交换判断,让A链表始终为最长的。
142.环形链表II
这道题的难点不是单纯的处理方法,而是涉及到一些数学运算。刚拿到的时候,完全没有优解的思路。多写几次记住思路,并且能自己复述出来就是目标。方法就是双指针,fast每次走2步,slow每次走1步。
public class Solution {
public ListNode detectCycle(ListNode head) {
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 index2;
}
}
return null;
}
}