leetcode笔记——92反转链表Ⅱ

题目:

反转从位置 mn 的链表。请使用一趟扫描完成反转。

说明:
1 ≤ m ≤ n ≤ 链表长度。

示例:

输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

思路:网上百度了大神的解法,原文链接:https://www.jianshu.com/p/b85508a2e226。代码如下。这个代码也是leetcode中运行时间最快的代码。

我自己写代码碰见的问题:

(1)边界条件注意要判断是否m==n

(2)是cur不等于空

(3)最后输出的时候,没有写ta=ta.next;

(4)忘记写n--

代码:

public class reverseBetween {
    public static void reverseBetween(ListNode head, int m, int n) {

        if (head == null || head.next == null || m == n)
            return;
        ListNode normal = head, last = null, pre, cur, gra = new ListNode(0);
        gra.next = head;
        pre = gra;
        cur = head;
        while (cur != null) {
            if (m == 1) {
                normal = cur;
                // 链表反转,头拼接,返回是这个last节点是第n个节点后面的那一个节点
                last = reverseList(cur, pre, n);
                // 尾拼接,将n后面的那一个节点拼在最开始的m节点后面,此时经过反转,m节点已经是翻转中最后一个节点了
                normal.next = last;
                break;
            }
            cur = cur.next;
            pre = pre.next;
            m--;
            n--;
        }
        //return gra.next;
        //这里写了一个链表的输出
        //t1表示链表的头结点,当节点不为空时输出节点的值
        ListNode t1=gra.next;
        while(t1!=null){
            System.out.print(t1.val+" ");
            t1=t1.next;
        }

    }

    // 反转链表工具方法,反转当前节点与之后n个节点的子链表,头拼接
    private static ListNode reverseList(ListNode head, ListNode first, int n) {
        ListNode pre = null;
        ListNode next = head;
        while (n > 0) {
            ListNode tmp = next.next;
            next.next = pre;
            pre = next;
            next = tmp;
            n--;
        }
        first.next = pre;
        return next;
    }
    public static void main(String args[]){
        int m=2;
        int n=5;
        int list[]={1,2,3,4,5,6,7};
        //下面是创建一个链表
        //首先创建一个头结点
        ListNode head=new ListNode(list[0]);
        for(int i=1;i<=list.length-1;i++){
            //每次创建一个节点指向头结点
            ListNode cur=head;
            //首先先创建一个节点
            ListNode temp=new ListNode(list[i]);
            //然后找到链表的末尾
            while(cur.next!=null){
                cur=cur.next;

            }
            //把节点添加到最后
            cur.next=temp;

        }



        reverseBetween(head,m,n);



    }
}

执行最快的代码:

class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
		if (head == null) {
			return null;
		}
        ListNode p1 = head;
        ListNode p2 = head;
        ListNode p3 = null;
        if (m == 1) {
        	p1 = null;
        	p3 = head;
        } else {
        	while (m-- > 2) {
        		p1 = p1.next;
        	}
        	p3 = p1.next;
        }
        while (n-- > 1) {
        	p2 = p2.next;
        }
    	ListNode nexts = null;
        while (p3 != p2) {
        	nexts = p3.next;
        	p3.next = p2.next;
        	p2.next = p3;
        	p3 = nexts;
        }
        if (p1 != null) {
        	p1.next = p2;
            return head;
        }
        return p2;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值