For example:
Given 1->2->3->4->5->NULL
and k = 2
,
return 4->5->1->2->3->NULL
.
思路:对于数组来说,右旋的方法是两轮逆转。对于链表,结点的位置是逻辑相连的,右旋时只需要拆开两截在另一头接上,不需要移动链的内部,更不需要交换结点的元素。所以操作的关键是根据数字k,找到链表拆解的位置。注意k可以超过链表元素的个数,即右旋几圈跟没右旋一样。
代码一:
class Solution { public: ListNode *rotateRight(ListNode *head, int k) { if(head == NULL) return NULL; ListNode *p1, *p2; p1 = p2 = head; while(k > 0) { k--; p1 = p1->next; if(p1 == NULL)//循环跑圈,把k跑到0 p1 = head; } while(p1->next != NULL) { p1 = p1->next; p2 = p2->next; }//此时:p1指向链表尾结点,p2指向链表右旋位置 p1->next = head; head = p2->next; p2->next = NULL; return head; } };
代码二:也可以先求出链表长度,然后通过取模运算来计算旋转位置。当k很大的时候可以避免代码一循环跑圈。
class Solution { public: ListNode *rotateRight(ListNode *head, int k) { if(head == NULL || k == 0) return head; ListNode *p1, *p2; p1 = p2 = head; int n = 1; while(p1->next != NULL) //计算链表长度并记录尾结点 { n++; p1 = p1->next; } k = n - k%n; for(int i=1;i<k;i++) //找到新表尾 p2 = p2->next; p1->next = head; head = p2->next; p2->next = NULL; return head; } };