力扣记录:链表——206 反转链表,24 两两交换链表中的节点

本次题目

  • 206 反转链表
  • 24 两两交换链表中的节点

206 反转链表

  • (1)双指针法:不用定义一个新的链表,直接反转链表的指针指向。定义右指针(快指针)从头结点开始,指向要改变指针方向的节点,左指针(慢指针)从null开始,为右指针指向节点修改后的方向。两个指针依次向前移动,然后改变方向,直到右指针为null,左指针指向新的头结点(即原来链表中最后一个节点)。
  • 注意:改变右指针节点时需要先用临时指针将前进方向的下一个节点保存下来。
class Solution {
    public ListNode reverseList(ListNode head) {
        //定义左右指针和临时指针
        ListNode left = null;
        ListNode right = head;
        ListNode tmp = null;
        //开始循环
        while(right != null){
            tmp = right.next;
            right.next = left;
            left = right;
            right = tmp;
        }
        return left;
    }
}
  • (2)递归:同双指针,注意:第一次输入递归函数的值为初始化值。
class Solution {
    public ListNode reverseList(ListNode head) {
        //往递归函数中输入初始值,初始化
        return resverse(null, head);
    }
    //定义递归函数
    public ListNode resverse(ListNode left, ListNode right){
        //停止递归条件
        if(right == null){
            return left;
        }
        //定义临时指针
        ListNode tmp = null;
        //开始递归
        tmp = right.next;
        right.next = left;
        left = right;
        right = tmp;
        return resverse(left,right);
    }
}
  • (3)从后向前递归
  • 注意:递归调用在函数中间,递归时先不断调用,直到找到最后节点,返回时反序。
class Solution {
    public static ListNode reverseList(ListNode head) {
        //链表为空时直接返回
        if(head == null) return null;
        //当指向链表最后一个节点时直接返回
        if (head.next == null) return head;

        //递归调用,反转第二个节点开始往后的节点
        ListNode last = reverseList(head.next);
        //第一次到这里时head指向的是原来链表的倒数第二个节点,将链表原来最后一个节点指向倒数第二个节点
        //第i次到这里时head指向的是原来链表的倒数第i+1个节点,将原来链表倒数第i个节点指向倒数第i+1个节点
        //最后一次到这里时head指向的是原来链表的第一个节点,将链表原来第二个节点指向第一个节点,完成链表反向
        head.next.next = head;
        //此时的 head 节点为新链表方向的尾节点,next 需要指向 NULL
        head.next = null;
        return last;
    }
}

24 两两交换链表中的节点

  • 可以使用虚拟头结点,不用每次针对头结点单独处理。
  • 明确处理步骤:使用虚拟头结点指向头结点,此时需要交换此时的头结点1和头结点指向的下一个节点2,
    1. 将虚拟头结点指向2;
    2. 将2指向1;
    3. 将1指向2原来指向的下一个节点,在1之前先存为临时指针。
    4. 然后将虚拟头结点和头结点都向前一位,循环以上步骤,循环结束条件为头结点指向的下一个节点为最后一个节点或者头结点为最后一个节点。
  • 注意循环中需要重新定义节点等于虚拟头结点开始循环。
  • 递归:同上。可以debug看递归流程。
class Solution {
        public static ListNode swapPairs(ListNode head) {
        //使用虚拟头结点
        ListNode virtualHead = new ListNode(0);
        virtualHead.next = head;
        //重新定义节点等于虚拟头结点,防止循环中改变虚拟头结点的值
        ListNode pre = virtualHead;
        //循环终止条件
        while(pre.next != null && head.next != null){
            //定义临时变量
            ListNode tmp = head.next.next;
            //开始循环
            pre.next = head.next;
            head.next.next = head;
            head.next = tmp;
            //在第一轮循环时pre还是=virtualHead的
            //找到新的头结点(2)后修改pre,之后的改变不影响virtualHead
            pre = head;
            head = head.next;
        }
        return virtualHead.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值