代码随想录算法训练营Day04
两两交换链表中的节点
注意循环控制条件以及cur的位置
交换的是cur后面的两个节点的位置
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyHeadNode = new ListNode(0);
dummyHeadNode.next = head;
ListNode current = dummyHeadNode;
while(current.next!=null&¤t.next.next!=null){
ListNode temp = current.next;
ListNode temp1 = temp.next.next;
current.next = temp.next;
temp.next.next = temp;
temp.next = temp1;
current = temp;
}
return dummyHeadNode.next;
}
}
删除链表倒数第n个节点
双指针是最优解法,也可以用笨方法,倒数第n个是正数第size-n个,再用deleteAtIndex删除即可
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//用到了双指针的思想,一个快指针一个慢指针,快指针先往后移动,然后同时向后移动,当快指针移动到末尾时,慢指针移动到要删除元素的位置
ListNode dummyHeadNode = new ListNode(0,head);
ListNode slow = dummyHeadNode;
ListNode fast = dummyHeadNode;
for(int i = 0;i<n+1;i++){
fast = fast.next;
}
while(fast!=null){
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummyHeadNode.next;
}
}
链表相交
双指针,保证链表的current指针齐头并进,直至遇到交点
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode dummyHeadNodeA = new ListNode(0,headA);
ListNode dummyHeadNodeB = new ListNode(0,headB);
ListNode currentA = dummyHeadNodeA;
ListNode currentB = dummyHeadNodeB;
int sizeA = 0;
int sizeB = 0;
sizeA = getSize(currentA);
sizeB = getSize(currentB);
int dif = 0;
if(sizeA>sizeB){
dif = sizeA-sizeB;
for(int i = 0;i<dif;i++){
currentA = currentA.next;
}
}else{
dif = sizeB-sizeA;
for(int i = 0;i<dif;i++){
currentB = currentB.next;
}
}
while(currentA!=currentB){
currentA = currentA.next;
currentB = currentB.next;
}
return currentA;
}
public int getSize(ListNode current){
int size = 0;
while(current!=null){
current = current.next;
size++;
}
return size;
}
}
环形链表
这里不用dummy Head Node了
成环的条件
-
定义两个指针:
-
慢指针(
slow):每次移动一个节点。 -
快指针(
fast):每次移动两个节点。
-
-
操作步骤:
-
两个指针从链表头节点同时开始移动。
-
如果链表中存在环,快指针和慢指针最终会在环内相遇。
-
如果链表没有环,快指针会先到达链表末尾(即指向
null)。
-
-
原理:
-
在环内,快指针的速度比慢指针快,因此它会不断追赶慢指针并最终相遇。
-
时间复杂度为𝑂(𝑛),空间复杂度为 𝑂(1)。
-
找到环的入口
-
当快慢指针在环内相遇后,将其中一个指针(如
slow)重新放回链表头。 -
两个指针以相同速度(每次移动一个节点)继续移动。
-
它们再次相遇时,相遇的节点即为环的入口。
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) {
return null; // 链表为空或只有一个节点时,不可能有环
}
ListNode slow = head;
ListNode fast = head;
do {
if (fast == null || fast.next == null) {
return null; // 快指针先到末尾,这里考虑了奇偶数的问题,说明没有环
}
slow = slow.next; // 慢指针移动一步
fast = fast.next.next; // 快指针移动两步
} while (slow != fast);//为什么do-while?因为一开始将slow和fast都赋值为head,根本不进循环啊!!
slow = head;
while(slow!=fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}

浙公网安备 33010602011771号