一,24. 两两交换链表中的节点
解法一:设置虚节点,直接开始
/**
* 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 dummyNode=new ListNode();
ListNode pre=dummyNode;
dummyNode.next=head;
while(pre.next!=null&&pre.next.next!=null)
{
ListNode temp=head.next.next;
pre.next=head.next;
head.next.next=head;
head.next=temp;
pre=head;
head=head.next;
}
return dummyNode.next;
}
}
解法二:递归法,有点难,不是太理解。回顾的时候尝试自己写一下。
/**
* 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 next=head.next;
ListNode newNode=swapPairs(next.next);
next.next=head;
head.next=newNode;
return next;
}
}
二,19.删除链表的倒数第N个节点
/**
* 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 dummy=new ListNode();
ListNode slow=dummy;
ListNode fast=dummy;
dummy.next=head;
if(n<0)
return dummy;
for(int i=0;i<=n;i++)
{
fast=fast.next;
}
while(fast!=null)
{
fast=fast.next;
slow=slow.next;
}
slow.next=slow.next.next;
return dummy.next;
}
}
这道题看了思路再去写还是挺简单的。
三,面试题 02.07. 链表相交
题目链接/文章讲解:代码随想录
/**
* 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 lenA=0;
int lenB=0;
while(curA!=null)
{
curA=curA.next;//求链表A的长度
lenA++;
}
while(curB!=null)
{
curB=curB.next;//求链表B的长度
lenB++;
}
curA=headA;//指针复位
curB=headB;
//找到最长的链表,长度才可以用大的减小的,默认链表A是最长的
if(lenA<lenB)
{
int temp=lenA;
lenA=lenB;
lenB=temp;
//同时指向链表的指针也要交换
ListNode tempNode=curA;
curA=curB;
curB=tempNode;
}
int size=lenA-lenB;//把链表A和链表B末尾对齐,移动A的指针size个
for(int i=0;i<size;i++)//可以改为while(size-->0)
{
curA=curA.next;
}
while(curA!=null)
{
if(curA==curB)//说明此时相交,直接返回
return curA;
curA=curA.next;//没有找到,继续移动指针,寻找下一个
curB=curB.next;
}
return null;
}
}
思路清楚了,代码还是好写的,注意细节问题
四,142.环形链表II(快慢指针法)
题目链接/文章讲解/视频讲解:代码随想录
while(fast!=null&&fast.next!=null)
这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
也就是在相遇节点处,定义一个指针index1,在头结点处定一个指针index2。
让index1和index2同时移动,每次移动一个节点, 那么他们相遇的地方就是 环形入口的节点。
那么 n如果大于1是什么情况呢,就是fast指针在环形转n圈之后才遇到 slow指针。
其实这种情况和n为1的时候 效果是一样的,一样可以通过这个方法找到 环形的入口节点,只不过,index1 指针在环里 多转了(n-1)圈,然后再遇到index2,相遇点依然是环形的入口节点。
/**
* 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(fast!=null&&fast.next!=null)
{
slow=slow.next;
fast=fast.next.next;
if(slow==fast)
{
ListNode index1=slow;//改成fast也可,此时两者是相等的
ListNode index2=head;
while(index1!=index2)
{
index1=index1.next;
index2=index2.next;
}
return index1;//改成index2也可,此时两者是相等的
}
}
return null;
}
}
其中
while(fast!=null&&fast.next!=null)
不可把while改成if,要不断地跟新指针,必定是循环才行。