📅  最后修改于: 2023-12-03 14:43:03.620000             🧑  作者: Mango
在本文中,将讲解如何使用Java语言编写程序,实现链表的子列表从位置M到N向右旋转K位的功能。
具体来说,给定一个链表和三个整数M、N和K,将链表中从第M个节点到第N个节点形成的子列表向右旋转K次。例如,给定链表为1->2->3->4->5->NULL,M = 2,N = 4,K = 1,则应该将链表变为1->4->2->3->5->NULL。
这个问题的一个解决方案是首先将链表从第M个节点到第N个节点截取出来形成一个新的链表,然后将这个新链表向右旋转K次,最后再将这个新链表接回原来的链表中原来的位置。
下面是这个问题的Java实现代码,注释中包含了详细的解释。
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n, int k) {
// 将链表分成三部分:前缀、子链表、后缀
ListNode pre = null;
ListNode cur = head;
for (int i = 1; i < m; i++) {
pre = cur;
cur = cur.next;
}
ListNode left = pre;
ListNode subList = cur;
for (int i = m; i <= n; i++) {
pre = cur;
cur = cur.next;
}
ListNode right = cur;
// 截取子链表并将其反转
pre.next = null;
reverse(subList);
// 将反转后的子链表旋转k次
int size = n - m + 1;
k = k % size;
if (k < 0) {
k += size;
}
if (k > 0) {
subList = rotate(subList, k);
}
// 将子链表接回原链表中
if (left != null) {
left.next = subList;
} else {
head = subList;
}
while (subList.next != null) {
subList = subList.next;
}
subList.next = right;
return head;
}
// 反转链表
private ListNode reverse(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTmp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTmp;
}
return prev;
}
// 将链表旋转k次
private ListNode rotate(ListNode head, int k) {
if (head == null || head.next == null || k == 0) {
return head;
}
int size = 1;
ListNode tail = head;
while (tail.next != null) {
tail = tail.next;
size++;
}
k = size - k % size;
if (k == size) {
return head;
}
tail.next = head;
for (int i = 0; i < k; i++) {
tail = tail.next;
}
ListNode newHead = tail.next;
tail.next = null;
return newHead;
}
}
使用以下测试样例进行测试,确保程序正常运行:
输入:head = {1,2,3,4,5}, m = 2, n = 4, k = 1
输出:{1,4,2,3,5}
输入:head = {1,2,3,4,5}, m = 2, n = 4, k = 2
输出:{1,3,4,2,5}