leetcode算法题-链表-反转链表II

问题描述:

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。

代码实现

  • 两种算法 递归和迭代
package com.leetcode.链表;

/**
 * Author:markusZhang
 * VM Args:
 * Date:Create in 2020/2/4 14:18
 */
public class 反转链表II {
    static class ListNode{
        int val;
        ListNode next;
        public ListNode(){}
        public ListNode(int val){
            this.val = val;
        }
    }
    private boolean stop; //用于终止递归的条件
    private ListNode left;
    public ListNode reverseBetween(ListNode head, int m, int n) {
        this.left = head;
        this.stop = false;
        this.recurseAndReverse(head,2,4);
        return head;
    }
    public void recurseAndReverse(ListNode right,int m,int n){
        //最基本的终止递归的条件
        if(n==1){
            return ;
        }
        //同时移动两个指针
        right = right.next;
        if(m>1){
            this.left = this.left.next;
        }
        //递归,直到两个指针到达各自相应的位置
        this.recurseAndReverse(right,m-1,n-1);
        //当两个指针位于一个节点上或者左指针已经越过了右指针,把stop改为true,然后结束
        if(this.left==right || right.next == this.left){
            this.stop = true;
        }
        //不是停止条件时,交换两个指针的所指向节点的值
        if(!stop){
            int t = this.left.val;
            this.left.val = right.val;
            right.val = t;
            //然后将左指针向右移动一个位置,通过回溯,右指针向左移动一个位置
            this.left = this.left.next;
        }
    }
    public ListNode reverseBetween1(ListNode head, int m, int n) {
        //鲁棒
        if(head==null){
            return null;
        }
        //定义两个指针 prev curr
        ListNode prev = null;
        ListNode curr = head;
        //移动指针到第m个节点的前一个节点
        while(m>1){
            prev = curr;
            curr = curr.next;
            m--;
            n--;
        }
        //System.out.println(n);
        //定义 con tail指针 con的指针指向第m节点的前一个节点
        //                  tail的指针指向当前需要进行反转的链表的最后一个节点
        ListNode con = prev;
        ListNode tail = curr;
        ListNode third = null;
        while(n>0){
            third = curr.next;
            curr.next = prev;
            prev = curr;
            curr = third;
            n--;
        }
        //连接不发生反转的节点与发生反转的节点,确保整个链表不发生丢失
        if(con!=null) {
            con.next = prev;
        }else{
            head = prev;
        }
        tail.next = curr;
        return head;
    }
    public static void main(String[] args) {
        ListNode p = new ListNode(1);
        ListNode p1 = new ListNode(2);
        p.next = p1;
        ListNode p2 = new ListNode(3);
        p1.next = p2;
        ListNode p3 = new ListNode(4);
        p2.next = p3;
        ListNode p4 = new ListNode(5);
        p3.next = p4;
        ListNode head = new 反转链表II().reverseBetween1(p,2,4);
        while(head!=null){
            System.out.print(head.val+" ");
            head = head.next;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/MarkusZhang/article/details/104171743