24. 反转链表&&92. 反转链表 II

题目-反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

思路

  • 链表为null直接返回null
  • pre当前节点的前驱节点
  • cur当前节点
    循环cur当前节点为空退出:
    1. 临时节点保存cur当前节点的后继节点
    2. cur,next=pre修改当前节点指向pre前驱节点
    3. pre=cur后移
    4. cur后移
  • 返回新链表pre前驱节点作为头结点
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode pre=null;
        ListNode cur=head;
        //坑:p2.next=p1把p2的next发生改变
        //p2=p2.next;不会后移而是指向p1
        //造成p1和p2死循环
//         while(p2!=null){
//             p2.next=p1;
//             p1=p2;
//             p2=p2.next;
            
//         }
        //学到一个技巧:移动的节点最好临时变量保存,这种坑还是很多一定要注意注意
        //正确写法:临时变量保存p2的next
        while(cur!=null){
            //临时变量保存反之丢失
            ListNode curNext=cur.next;
            cur.next=pre;
            pre=cur;
            cur=curNext;
        }
        return pre;
        
    }
}

复杂度

时间复杂度O(n):遍历整个链表
空间复杂度O(1):变量都是常数阶

题目-反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:
在这里插入图片描述

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
示例 2:
输入:head = [5], left = 1, right = 1
输出:[5]

思路

  • 拆分
  • 反转
  • 连接
  • 一个节点或者空链表直接返回head
  • 哑节点标志表头
  • 拆分:左边界left->1,右边界right->0
  • 翻转中间
  • 再连接还原
/**
 * 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 reverseBetween(ListNode head, int left, int right) {
        //空或者一个节点不用翻转
        if(head==null||head.next==null){
            return head;
        }

        //哑节点
        ListNode dHead=new ListNode(-1);
        dHead.next=head;


        ListNode cur=dHead;
        while(left-->1){
            if(cur!=null){
                cur=cur.next;
            }
        }
        //左边界
        ListNode l=cur;

        //翻转部分头
        ListNode reverseHead=cur.next;

        cur=dHead;
        while(right-->0){
            if(cur!=null){
                cur=cur.next;
            }

        }

        //右边界
        ListNode r=cur.next;
        ListNode reverseTail=cur;

        //拆分
        l.next=null;
        reverseTail.next=null;

        //翻转
        ListNode pre=null;
        cur=reverseHead;
        while(cur!=null){
            ListNode curNext=cur.next;
            cur.next=pre;
            pre=cur;
            cur=curNext;
        }

        //拼接

        l.next=pre;
        reverseHead.next=r;

        return dHead.next;

    }
}

复杂度

时间复杂度O(n)
空间复杂度O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值