代码随想录算法训练营第四天| 19.删除链表的倒数第N个节点 24. 两两交换链表中的节点 面试题 02.07. 链表相交 142.环形链表II
目录
19 删除链表的第N个节点
我们需要删除链表的倒数第n个节点并且返回头节点。
设置虚拟头节点nh,将nh的next指针赋值为head,使得头节点与其他节点统一起来。
我们可以通过设置快慢指针的方式处理本题,快指针fastNode,slowNode均初始化为nh,先使fastNode前进n。
此时快
慢指针同时向前遍历,当fastNode为null或者fastNode的next为null时退出while循环,slowNode此时所处的位置即为的要删除的节点的前一个位置。
接下来只需要通过链表删除操作删除slowNode的下一个节点就完成了对指定节点的删除。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode nh = new ListNode(0);
nh.next = head;
ListNode fastNode = nh;
ListNode slowNode = nh;
for(int i = 0;i < n;i++)fastNode = fastNode.next;
while(fastNode != null && fastNode.next != null){
fastNode = fastNode.next;
slowNode = slowNode.next;
}
slowNode.next = slowNode.next.next;
return nh.next;
}
}
时间复杂度O(n),空间复杂度O(n)。
面试题 02.07.链表相交
先设置ListNode curA = headA与ListNode curB = headB,通过curA与curB依次遍历headA与headB分别取得二者长度,再重置curA与curB为各自初始值。通过交换操作使得较长的为curA,较短的为curB,计算二者长度差值diff,使curA前进diff,此时curA与curB剩余节点个数相同,如果二者存在交点,则一定是在之后的节点中,同时遍历这两个节点,在循环中进行判断。
ppublic class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int sizA = 0,sizB = 0;
while(curA != null){
sizA++;
curA = curA.next;
}
while(curB != null){
sizB++;
curB = curB.next;
}
curA = headA;
curB = headB;
if(sizB > sizA){
ListNode tmpNode = curA;
curA = curB;
curB = tmpNode;
int tmp = sizA;
sizA = sizB;
sizB = tmp;
}
int diff = sizA - sizB;
for(int i = 0;i < diff;i++)curA = curA.next;
while(curA != null){
if(curA == curB)return curA;
curA = curA.next;
curB = curB.next;
}
return null;
}
}
时间复杂度O(m + n),空间复杂度O(n)。
24 两两交换链表中的节点
递归
class Solution {
public ListNode swapPairs(ListNode head) {
if(head == null || head.next == null)return head;
ListNode newHead = head.next;
head.next = swapPairs(newHead.next);
newHead.next = head;
return newHead;
}
}
迭代
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dumyHead = new ListNode(0);
dumyHead.next = head;
ListNode cur = dumyHead;
ListNode firNode;
ListNode secondNode;
ListNode tmp;
while(cur.next != null && cur.next.next != null){
tmp = cur.next.next.next;
firNode = cur.next;
secondNode = cur.next.next;
cur.next = secondNode;
secondNode.next = firNode;
firNode.next = tmp;
cur = firNode;
}
return dumyHead.next;
}
}
142 环形链表II
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){//此时相遇
ListNode index1 = head;
ListNode index2 = fast;
while(index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
哈希表
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode cur = head;
Set<ListNode> aw = new HashSet<ListNode>();
while(cur != null){
if(aw.contains(cur)){
return cur;
}
else aw.add(cur);
cur = cur.next;
}
return null;
}
}

慢指针同时向前遍历,当fastNode为null或者fastNode的next为null时退出while循环,slowNode此时所处的位置即为的要删除的节点的前一个位置。

浙公网安备 33010602011771号