19. 删除链表的倒数第 N 个结点
//先遍历一遍得到长度,然后在遍历一遍得到要删除节点的前一个节点,进行删除操作
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode current = head;
int length = 0;
while(current!=null){
length++;
current=current.next;
}
ListNode dumpy = new ListNode(0,head); //增加首部节点方便处理
current = dumpy;
int count = 0;
while(current.next!=null){
if(count == length-n) break;
count++;
current = current.next;
}
current.next = current.next.next;
return dumpy.next;
}
}
24. 两两交换链表中的节点
要求:不修改节点内部的值,仅进行节点交换。
- 创建一个虚拟头节点
dummy
,它的next
指向原链表的头节点。这是为了方便处理头节点的交换。- 用指针
prev
指向dummy
,curr
指向原链表的头节点。- 当
curr
和curr.next
都不为空时(成对节点才交换),进行如下操作:
- 保存
curr.next
为nextNode
。prev.next
指向nextNode
。curr.next
指向nextNode.next
。(保证不会断链)nextNode.next
指向curr
。- 更新
prev
为curr
,curr
为curr.next
。- 所以一次交换需要操作三个指针 pre current current.next
- 最后返回
dummy.next
,即交换后链表的头节点
举例:
假设我们有一个链表
1 -> 2 -> 3 -> 4 -> null
,创建虚拟头节点dummy
,它的next
指向链表头节点1
,此时设置prev = dummy
,curr = 1
。dummy -> 1 -> 2 -> 3 -> 4 -> null prev curr
第一次交换
- 保存
curr.next
即节点2
为nextNode
。prev.next
指向nextNode
(也就是让虚拟头节点dummy
的next
指向2
)。curr.next
指向nextNode.next
(节点1
的next
指向3
)。(保证不会断链)nextNode.next
指向curr
(节点2
的next
指向1
)交换后状态如下:
dummy -> 2 -> 1 -> 3 -> 4 -> null prev curr
此时更新
prev = curr
(prev
指向1
),curr = curr.next
(curr
指向3
)dummy -> 2 -> 1 -> 3 -> 4 -> null prev curr
第二次交换重复上述交换步骤。
public class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode prev = dummy;
ListNode curr = head;
//成对节点才交换
while (curr != null && curr.next != null) {
ListNode nextNode = curr.next;
prev.next = nextNode;
curr.next = nextNode.next; //保证不会断链
nextNode.next = curr;
prev = curr;
curr = curr.next;
}
return dummy.next;
}
}