迭代反转单链表

单链表的定义如下:

class LinkNode {
    int val;
    LinkNode next = null;
    LinkNode (int val) {this.val = val;}
}

对单链表的反转考虑两种思路:迭代 和 递归。本篇只列出迭代方式,下篇列出递归方式(https://www.cnblogs.com/PlumBlossoms/p/14211608.html),以 {1,2,3,4,5,6,7} 为例 :

1. 反转整个链表,即 [head, Null) 区间,反转后为{7,6,5,4,3,2,1} ,pre 指向节点 7。

  public LinkNode ReverseList(LinkNode head) {
        LinkNode pre = null, cur = head, next = head;
        while (cur != null) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;         
 } 

2. 仅反转链表的前 N 个节点,即 [head, b) 区间,假设N=5,反转后为{5,4,3,2,1},pre 指向节点 5。

public LinkNode ReverseN(LinkNode head, LinkNode b) {
        LinkNode pre = null, cur = head, next = head;
        while (cur != b) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;        
} 

3. 仅反转区间 [a, b) 内的节点

public LinkNode ReverseAB(LinkNode a, LinkNode b) {
        LinkNode pre = null, cur = a, next = a;
        while (cur != b) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;        
    }

4. 以 K 个节点为一组进行反转,如 K=2,反转后为{2,1,4,3,6,5,7};K=3,反转后为{3,2,1,6,5,4,7}。

public LinkNode ReverseKGroup(LinkNode head, int k) {
        if (head == null) return null;
        //[a, b) 区间包含 K 个节点
        LinkNode a = head, b = head;
        for (int i = 0; i < k; i++) {
            //区间不足K个,不需要反转
            if (b == null) return head;
            b = b.next;
        }
        //开始反转
        LinkNode newHead = ReverseAB(a, b);
        //将已反转好的组与未反转好的组连起来
        a.next = ReverseKGroup(b, k);
        return newHead;
    }
posted @ 2020-12-30 15:56  wamxz  阅读(112)  评论(0)    收藏  举报