给定一个链表,旋转链表,将链表每个节点向右移动 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
解题思路:
1. 获取链表的规模mod,K=K%mod。以避免多余的旋转。
2. 存储链表的后K+1个结点地址data(这涉及到如果位移到链表的倒数第K+1个节点,遍历一次链表即可,详细请看代码)。
ListNode*p = head;
ListNode*q = head;
int move = k;
while (move) { q = q->next; move--; }
while (q->next) { q = q->next; p = p->next; }
3. 进行K 次末尾结点移动到表头的操作。
data[i - 2]->next = data[i - 1]->next;
data[i - 1]->next = head;
swap(head, data[i - 1]);
class Solution { public: ListNode* rotateRight(ListNode* head, int k) { if (head == NULL||head->next==NULL) return head; //获取链表的规模 int size = 0; ListNode*p = head; ListNode*q = head; while (p) { size++; p = p->next; } k = k%size;//去掉多余的旋转 p = head; if (k == 0) return head; int move = k; while (move) { q = q->next; move--; } while (q->next) { q = q->next; p = p->next; } vector<ListNode*> data; while (p) { data.push_back(p); p = p->next; } for (int i = data.size(); i >= 2; i--) { //将当前的节点移动的表头 data[i - 2]->next = data[i - 1]->next; data[i - 1]->next = head; swap(head, data[i - 1]); } return head; } }; |