lintcode 算法-- 36. 翻转链表 II

算法要求

36. 翻转链表 II
中文English
翻转链表中第m个节点到第n个节点的部分

样例
例1:

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

输入: 1->2->3->4->NULL, m = 2 and n = 3, 
输出: 1->3->2->4->NULL.
挑战
Reverse it in-place and in one-pass

注意事项
m,n满足1 ≤ m ≤ n ≤ 链表长度

算法思路

这一道算法题,是在 lintcode 算法-- 35. 翻转链表 的基础上衍生出来的。如果没有思路的话,请先研究之前的算法思想
这个算法的解决思路在于,从 m处开始翻转,到n处结束翻转。并将翻转后的链表链接到原来的链表上去?

  • 通过m 次循坏,定位到开始翻转链表的位置,并记录 开始翻转链表的上一个节点 pre 和 翻转链表的开始节点 first 。其中 lastNode = first,表示链表翻转完后,需要指向未翻转的链表。
  • 通过非递归 的方式 ,从m处开始遍历 n -m + 1 次,结束。lastNode 指向剩余未翻转的节点即可。

算法实现

package com.lintcode.easy;
public class ReverseBetween {

    /**
     * 根据 “翻转链表 Reverse ”的思路
     * 1.链表从m处开始翻转
     * 2.链表翻转到 n 处结束
     * @param head
     * @param m
     * @param n
     * @return
     */
    public static ListNode reverseBetween(ListNode head, int m, int n) {

        ListNode first = head;
        ListNode sencode = null;
        ListNode pre = new ListNode(-1);
        ListNode temp = pre;
        pre.next = head;
        // 通过循坏,定位到开始翻转链表的位置,并记录 开始翻转链表的上一个节点  pre 和 翻转链表的开始节点 first 
        for(int i = 0; i < m - 1; i++){
            first = first.next;
            pre = pre.next;
        }
        ListNode reverseHead = null; // 用来存放中间的结果数据的
        // first 此时表示的是最后连接的节点
        ListNode lastNode = first;
        for(int i = 0; i < n - m + 1; i++){
            sencode = first.next;
            first.next = reverseHead;
            reverseHead = first;
            first = sencode;
        }
        pre.next = reverseHead;
        // 翻转后的链表的尾部,如何正确到连接到剩余未翻转的链表
        lastNode.next = sencode;
        return temp.next;
    }

    public static void main(String[] args) {
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);
        ListNode node5 = new ListNode(5);

        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
//        node4.next = node5;

//        ListNode reverseNode = reverseBetween(node1,2,4);
        ListNode reverseNode = reverseBetween(node1,2,3);
        while(reverseNode != null){
            System.out.print(reverseNode.val + " -> ");
            reverseNode = reverseNode.next;
        }
        System.out.print("null");
    }
}

class ListNode {
	int val;
	ListNode next;

	public ListNode(int x) {
		this.val = x;
		this.next = null;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值