两两交换链表中的节点
注意循环控制条件以及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;}
}