两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
该题两思路分别为迭代和递归。
- 递归
swap函数每次处理两个节点的互相替换,并且替换后将新的头节点返回。
代码如下:
public static ListNode swapPairs(ListNode head) {
//修改前后两两节点的
//返回头结点,尝试使用递归方式
if(head==null)return null;
if(head.next==null) return head;
ListNode pre=head;
ListNode cur=head.next;
ListNode nextNode=cur.next;
cur.next=pre;
pre.next=swapPairs(nextNode);
return cur;
}
- 迭代
迭代的概念与递归类似
代码如下:
public static ListNode swapPairs1(ListNode head) {
//修改前后两两节点的
//返回头结点,尝试使用递归方式
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode pre=dummy;
ListNode cur=head;
while(cur!=null&&cur.next!=null){
ListNode twonext=cur.next.next;
pre.next=cur.next;
cur.next.next=cur;
cur.next=twonext;
pre=pre.next.next;
cur=twonext;
}
return dummy.next;
}
- 第一思路是双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode pre=dummy;
ListNode cur=head;
ListNode fast=head;
for(int i=0;i<n;i++){
if(fast==null)return null;
fast=fast.next;
}
while(fast!=null){
cur=cur.next;
fast=fast.next;
pre=pre.next;
}
pre.next=cur.next;
return dummy.next;
}
-
还可以用递归回退法来完成
-
使用计算节点法进行计算
面试题 02.07. 链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
- 思路:分别计算两个链表的长度,去除掉长的链表的前面一部分,保证剩下的部分长度相当,然后再去迭代,判断节点是否一致(保证地址一致而不是大小一致)
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode l1=headA;
ListNode l2=headB;
int countA=0;
int countB=0;
while(l1!=null){
countA++;
l1=l1.next;
}
while(l2!=null){
countB++;
l2=l2.next;
}
if(countA>countB){
ListNode temp=headB;
headB=headA;
headA=temp;
int temp1=countB;
countB=countA;
countA=temp1;
}
int gap=countB-countA;
while(gap>0){
headB=headB.next;
gap--;
}
while(headA!=null){
if(headA==headB){
return headA;
}else{
headA=headA.next;
headB=headB.next;
}
}
return null;
}
时间复杂为O(n+m)
环形链表
public ListNode detectCycle(ListNode head) {
if(head==null||head.next==null)return null;
ListNode fast=head;
ListNode slow=head;
while(fast.next!=null&&fast.next.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
fast=head;
while(fast!=slow){
fast=fast.next;
slow=slow.next;
}
return fast;
}
}
return null;
}