题解 | #牛群的重新排列#
牛群的重新排列
https://www.nowcoder.com/practice/5183605e4ef147a5a1639ceedd447838
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 * @param left int整型 * @param right int整型 * @return ListNode类 */ public ListNode reverseBetween (ListNode head, int left, int right) { // write code here if (head == null || head.next == null || left == right) return head; ListNode hair = new ListNode(0), cur = hair; hair.next = head; for (int i = 0; i < left - 1; i++) cur = cur.next; cur.next = reverseK(cur.next, right - left + 1); return hair.next; } private ListNode reverseK(ListNode head, int k) { ListNode p = null, cur = head, next; while (k-- > 0) { next = cur.next; cur.next = p; p = cur; cur = next; } head.next = cur; return p; } }
- 单向链表 K个一组翻转的变种题,首先可以先写一个 reverseK 方法
- 定义一个虚拟节点 p、一个用于遍历的指针 cur、以及用于记录下一个遍历的 next
- 循环翻转 k 次,每次先记录 next,然后 cur 指向的节点翻转 即 cur.next = p;
- 然后 p 先后走,cur 向后走
- 最后循环出来时,p就是翻转之后的头节点,同时注意将head与cur连接上
- 回到区间翻转 reverseBetween 方法中
- 首先做一些边界值判断,若链表为null、或者只有一个节点、或者翻转元素只有一个(即 left==right),则不需要翻转,直接返回
- 然后就是老套路,定义一个虚拟头节点 hair,并指向 head;定义一个遍历的指针 cur,指向 hair
- 循环 left-1 次,找到翻转左区间的前一个节点 cur
- 调用 reverseK 方法,并将返回值与cur对接上
- 最后返回 hair.next 即为区间翻转后的链表的结果
线性表基础 文章被收录于专栏
链表、递归、栈