题目大意:轮转链表,例子如下:
法一:根据单链表节点个数,来重新确定k值需要轮转的节点个数,然后将链表分割成前面的和后面的链表,然后将两个链表连接起来即可。代码如下(耗时17ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public ListNode rotateRight(ListNode head, int k) { 2 //如果链表为空或不需要rotate,直接返回原链表 3 if(k == 0 || head == null) { 4 return head; 5 } 6 //记录原链表头节点 7 ListNode tmpHead = head; 8 //计算链表长度 9 int len = 0; 10 while(head != null) { 11 len++; 12 head = head.next; 13 } 14 //计算需要rotate的实际数量 15 k = k % len; 16 //如果不需要rotate直接返回原链表 17 if(k == 0) { 18 return tmpHead; 19 } 20 //计算rotate前面需要换到后面的数量 21 int pre = len - k, cnt = 0; 22 head = tmpHead; 23 //开始分割前面需要换到后面的链表节点,用postHead记录头节点 24 ListNode post = null, postHead = post; 25 while(cnt < pre) { 26 cnt++; 27 //如果头节点为空,单独处理,由于前面post=null,所以这里postHead需要重新赋值 28 if(post == null) { 29 post = head; 30 postHead = post; 31 } 32 //尾插 33 else { 34 post.next = head; 35 post = head; 36 } 37 head = head.next; 38 } 39 //由于是最后一个节点所以要next=null 40 post.next = null; 41 //分割后面需要换到前面的链表节点,用resHead记录头节点,与前面类似 42 ListNode res = null, resHead = res; 43 while(head != null) { 44 if(res == null) { 45 res = head; 46 resHead = res; 47 } 48 else { 49 res.next = head; 50 res = head; 51 } 52 head = head.next; 53 } 54 //将分割的两个单链表连接起来 55 res.next = postHead; 56 //返回头节点即可 57 return resHead; 58 }
法二(借鉴):根据单链表节点个数,来重新确定k值需要轮转的节点个数,然后将链表连接成循环链表,确定前面需要翻转的末节点位置,定位最终链表的头节点,然后将末节点next=null即可,这样就不用分割单链表。代码如下(耗时17ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public ListNode rotateRight(ListNode head, int k) { 2 if(head == null) { 3 return head; 4 } 5 int len = 1; 6 ListNode cur = head; 7 while(cur.next != null) { 8 len++; 9 cur = cur.next; 10 } 11 //形成循环单链表 12 cur.next = head; 13 //找到前面翻转的最末节点位置 14 int pre = len - k % len; 15 for(int i = 0; i < pre; i++) { 16 cur = cur.next; 17 } 18 //记录头节点,由于是循环链表,所以已经相连了 19 ListNode res = cur.next; 20 //将末节点next=null 21 cur.next = null; 22 return res; 23 }