一、两两交换链表中的节点(LeetCode24)
设置虚拟头结点
/**
* 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 dummyHead = new ListNode(-1,head); //设置虚拟头结点
dummyHead.next = head;
ListNode currentHead = dummyHead; //设置临时指针节点
ListNode tem = null,tem1 = null; //设置临时保存节点
while(currentHead.next!=null&¤tHead.next.next!=null){
tem = currentHead.next;
tem1 = currentHead.next.next.next;
currentHead.next = currentHead.next.next;
currentHead.next.next = tem;
tem.next = tem1;
currentHead = currentHead.next.next; //相邻两个节点交换位置后,指针后移两位
}
return dummyHead.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;
}
}
二、删除链表的倒数第N个节点(LeetCode19)
双指针
/**
* 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 dummyHead = new ListNode(-1,head);
ListNode fast = dummyHead;
ListNode slow = dummyHead;
//快慢指针相差n+1个节点
n++;
while(n-- > 0){
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyHead.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 currentA = headA;
ListNode currentB = headB;
int lengthA = 0, lengthB = 0;
while (currentA != null) { // 求链表A的长度
lengthA++;
currentA = currentA.next;
}
while (currentB != null) { // 求链表B的长度
lengthB++;
currentB = currentB.next;
}
//让当前指针重新回到头结点
currentA = headA;
currentB = headB;
//使其A为长链表
if(lengthA < lengthB){
//长度交换
int temLength = lengthA;
lengthA = lengthB;
lengthB = temLength;
//链表交换
ListNode newlist = currentA;
currentA = currentB;
currentB = newlist;
}
//末尾对齐,长链表当前指针移动与短链表指针对齐
for(int i = 0;i < lengthA - lengthB;i++){
currentA = currentA.next;
}
//循环找出公共点
while(currentA != null){
if(currentA == currentB){
return currentA;
}
currentA = currentA.next;
currentB = currentB.next;
}
return null;
}
}
四、环形链表II(LeetCode142)
双指针,判断环后再次设置双指针相遇即为入口
/**
* 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){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){ //有环
ListNode index1 = fast;
ListNode index2 = head;
// 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
while(index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}