编程导航算法通关村第二关|白银挑战—指定区间反转

 https://leetcode.cn/problems/reverse-linked-list-ii/

 头插法:

 /*
      头插法
      核心思路:一直在头部插入第一个节点后面的节点,实现反转
      1.找到要反转链表的位置,拿到要反转节点的前一个节点,目的指向反转头部节点
      2.定义一个节点指向头部,这个头部会一直往后移一直到right的位置
      3.利用这一个节点一直把它后面的节点放在头部
     */
    public ListNode reverseBetween01(ListNode head, int left, int right) {
        //找到要遍历节点的前一个节点,和当前头部节点
        ListNode dummyNode = new ListNode();
        dummyNode.next = head;
        ListNode pre = dummyNode;
        for (int i = 0; i < left - 1; i++) {
            pre = pre.next;
        }
        // while(left - 1 > 0) {
        //     pre = pre.next;
        //     left--;
        // }
        ListNode cur = pre.next;
        ListNode next;
        for (int i = 0; i < right - left; i++) {
            //next永远是cur节点的下一个节点
            next = cur.next;
            //移动节点位置
            cur.next = next.next;
            next.next = pre.next;
            //pre节点重新指向头部节点
            pre.next = next;
        }
        return dummyNode.next;
    }

传针引线法:

 //2.把要反转的左右节点切割,拿到要反转的节点,单独把节点反转,最后拼接节点即可
    public ListNode reverseBetween(ListNode head, int left, int right) {
        //使用虚拟节点操作,left可能为1,所以利用虚拟节点,让pre指向前面一个节点
        ListNode dummyNode = new ListNode();
        dummyNode.next = head;
        ListNode pre = dummyNode;
        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;
        //如果最后一个节点不为null,那么LeftNode后面的节点都会反转
        rightNode.next = null;
        //反转子链表
        reverseListNode(leftNode);
        //拼接链表因为链表进行反转了所以pre.next = rightNode
        pre.next = rightNode;
        leftNode.next = succ;
        return dummyNode.next;

    }

    public void reverseListNode(ListNode head) {
        ListNode newNode = null;
        while (head != null) {
            //记录后面的节点
            ListNode next = head.next;
            head.next = newNode;
            newNode = head;
            head = next;
        }
    }

你可能感兴趣的:(算法)