给定一个单链表,设计一个算法实现链表向右旋转 K 个位置。
举例: 给定 1->2->3->4->5->6->NULL, K=3
则 4->5->6->1->2->3->NULL
分析:
1. 这道题目的关键在于找到 尾节点和旋转后新链表的尾节点。 假设是 tail, new->tail.
然后只要进行 tail->next = head;
head = new_tail->next;
new_tail->next = NULL;
2. 找两个尾节点可以采用 双指针的方法。
注意到 这两个节点 间距是 K,(初始化,tail = new_tail = head;)
STEP 1:tail 从 head 出发,先走 k 步
STEP 2: new_tail 和 tail 同时往前走, 当 tail 指向尾节点时, new_tail 的位置即所求。
struct ListNode{ int val; ListNode *next; ListNode(int x) :val(x), next(NULL){} }; int Length(ListNode *head) { int len(0); for(; head; head = head->next, ++ len); return len; } ListNode* ReverseKList(ListNode *head, int k) { int length = Length(head); if(length < 2 || k == 0 || k == length) return head; if(k < 0) return ReverseKList(head, k + length); if(k > length) return ReverseKList(head, k % length); assert(k > 0 && k < length); ListNode *tail(head), *new_tail(head); // tail 先走K步 for(int i=0; i<k; ++i) tail = tail->next; // 一起走,知道 tail 指向尾节点 while(tail->next){ tail = tail->next; new_tail = new_tail->next; } // new_tail 指向旋转后的尾节点 tail->next = head; head = new_tail->next; new_tail->next = NULL; return head; }
原文:http://blog.csdn.net/shoulinjun/article/details/19678551