链表,旋转链表
1. 题目描述
难易度:中等
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-list
2. 思路分析
以示例1为例:
- 计算链表的长度length:
- 不难发现当k=0和k=5,他们旋转后的链表的头节点都是第一个节点,同样,k=1和k=6,他们旋转后的链表头节点都是第二个节点,以此类推
- index=k%length
- 找到下标为index的节点(下标从0开始)
- 此时找到的节点即为旋转后链表的头节点,记为newHead
- 将链表构成环
- 找到newHead的前驱节点即为旋转后链表的尾节点
- 将尾节点的next域置为null
- 返回newHead
3. 代码演示
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
class Solution1 {
public ListNode rotateRight(ListNode head, int k) {
if (head == null || k == 0) {
return head;
}
int length = 0;
ListNode cur = head;
ListNode newHead = null;
ListNode pre = head;
//遍历链表得到链表长度
while (cur != null) {
cur = cur.next;
length++;
}
k = k % length;
if (k == 0) {
return head;
}
//得到新的头节点的下标,下标从0开始
k = length - k;
cur = head;
//遍历,得到第k个节点
while (k > 0) {
pre = cur;
cur = cur.next;
k--;
}
newHead = cur;
//得到最后一个节点
while (cur.next != null) {
cur = cur.next;
}
//将链表构成环
cur.next = head;
//pre为新链表的最后一个节点,所以将next域置null
pre.next = null;
return newHead;
}
}