链表区间反转问题解析【算法通关村第二关白银挑战】

力扣对应题目:
LeetCode92:给你单链表的头指针head和两个整数Ieft和right,其中Ieft<=right。请你反转从位
置left到位置right的链表节点,返回反转后的链表。
示例 1:
链表区间反转问题解析【算法通关村第二关白银挑战】_第1张图片
输入:head = [1,2,3,4,5], left = 2, right = 4 输出:[1,4,3,2,5]


链表反转本文阐述两个方法,分别为头插法穿针引线法。前者主要借助虚拟头结点相比后者简单。

头插法

主要思想:遍历链表找到开始反转的头部,开始遍历反转,每到一个节点,让新的节点移动到起始位置。

链表区间反转问题解析【算法通关村第二关白银挑战】_第2张图片
上面的初看可能不好理解,至少我是这样的,下面是我画的每一次的变换具体操作。
链表区间反转问题解析【算法通关村第二关白银挑战】_第3张图片
C++代码:

ListNode* reverseBetween(ListNode* head, int left, int right) {
    //创建虚拟头结点,这个不移动
        ListNode * vir = (struct ListNode*)malloc(sizeof(struct ListNode)); 
        vir->next = head;//虚拟节点和链表相连
        ListNode * pre = vir;  //这是移动的虚拟节点。
    	//循环遍历到left前一个节点
        for(int i = 0; i < left - 1; i++) {
            pre = pre->next;
        }

        ListNode * cur = pre->next;//临时反转头结点
        ListNode * next;
        for(int i = 0; i < right - left; i++) {
            next = cur->next;
            //下面这三步可直接看上图
            cur->next = cur->next->next;
            next->next = pre->next;
            pre->next = next;
        }
        return vir->next;
    }

java代码:

public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode vir = new ListNode(0, head);
        ListNode pre = vir;
        for(int i = 0; i < left - 1; i++) {
            pre = pre.next;
        }

        ListNode cur = pre.next;
        ListNode next = new ListNode();
        for(int i = 0; i < right - left; i++) {
            next = cur.next;
            cur.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }
        return vir.next;
    }

穿针引线法

算法主要分两步:

  1. 将区间内的链表先反转。
  2. 将pre的next值指向反转后的头结点right,将反转后的尾部节点left的next指向succ

链表区间反转问题解析【算法通关村第二关白银挑战】_第4张图片
C++代码:

ListNode* reverseBetween(ListNode* head, int left, int right) {
        ListNode * vir = new ListNode(0, head);
        ListNode * pre = vir;
        for(int i = 0; i < left - 1; i++) {
            pre = pre->next;
        }

        ListNode * rightNode = pre;
        for(int i = 0; i < right - left + 1; i++) {
            rightNode = rightNode->next;
        }
        ListNode * LeftNode = pre->next;
        ListNode * succ = rightNode->next;
        rightNode->next = NULL;

        reverseList(LeftNode);

        pre->next = rightNode;
        LeftNode->next = succ;
        return vir->next;
    }
    void reverseList(ListNode * head) {
        ListNode * pre = NULL;
        ListNode * cur = head;
        while(cur) {
            ListNode * next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
    }

你可能感兴趣的:(算法,算法通关村第一期,链表,算法,数据结构)