两两交换链表中的节点
拿到题目的思考
交换两个链表中的数据,想到用递归方法去进行循环,从后向前拼接链表需要交换的数据。拼接的时候需要判断当前交换的两个值是否为null。代码如下:
class Solution {
public ListNode swapPairs(ListNode head) {
if(head==null){
return null;
}
return swap(head);
}
//递归法解决交换问题
public ListNode swap(ListNode head){
if(head==null){
return null;
}
if(head.next==null){
return head;
}
//拼凑最末尾的节点
ListNode lastNode = swap(head.next.next);
ListNode temp = new ListNode(head.val,lastNode);
ListNode preTemp = new ListNode(head.next.val,temp);
return preTemp;
}
}
观看教程后的思考
可以给链表设置一个虚拟的头结点,这样处理链表会方便一点,两两交换,需要判断循环的时候最后一个是否为奇数,奇数不用移动直接跳效果。添加虚拟节点的代码如下:
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dumyhead = new ListNode(-1); // 设置一个虚拟头结点
dumyhead.next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
ListNode cur = dumyhead;
ListNode temp; // 临时节点,保存两个节点后面的节点
ListNode firstnode; // 临时节点,保存两个节点之中的第一个节点
ListNode secondnode; // 临时节点,保存两个节点之中的第二个节点
while (cur.next != null && cur.next.next != null) {
temp = cur.next.next.next;
firstnode = cur.next;
secondnode = cur.next.next;
cur.next = secondnode; // 步骤一
secondnode.next = firstnode; // 步骤二
firstnode.next = temp; // 步骤三
cur = firstnode; // cur移动,准备下一轮交换
}
return dumyhead.next;
}
}
删除链表的倒数第 N 个结点
拿到题目的思考
最大的问题在于需要给链表进行计数,统计该链表总长度为多少是需要单独计数的,这样不可避免的需要两个循环,一个循环用来计数,另一个循环进行拼值。如果要一次循环解决这个问题不太现实。
观看教程后的思考
感觉对自己对快慢指针的理解还是不够到位。这里的n其实可以看做快慢指针的间隔,使用快指针多走间隔的距离,再利用快指针到末尾让慢指针删除它的下一个节点就可以。代码如下:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//双指针解决问题
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode leftPoint = dummy;
ListNode rightPoint = dummy;
for (int i = 0; i < n; i++) {
rightPoint = rightPoint.next;
}
while (rightPoint.next != null){
leftPoint = leftPoint.next;
rightPoint = rightPoint.next;
}
leftPoint.next=leftPoint.next.next;
return dummy.next;
}
}
快慢指针在进行迭代时,需要注意的是,因为n代表的是从后向前数第几个,所以实际上的两个节点的间隔实际上是n-1,我们用慢指针标记的节点其实是需要移除的节点的前一个节点,所以会变成快节点先走n个值。