题目要求
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.
其实这题的描述有些不妥当,确切的说是将最右侧的节点依次移到最左侧作为头结点,一直移动到右侧第k个节点后结束。
还是以1->2->3->4->5->NULL
为例
k=1 结果为:5->1->2->3->4->NULL
k=2 结果为:4->5->1->2->3->NULL
k=3 结果为:3->4->5->1->2->NULL
k=4 结果为:2->3->4->5->1->NULL
k=5 结果为:1->2->3->4->5->NULL
k=6 结果为:5->1->2->3->4->NULL
换句话说 当k的值超过了list的长度len的时候,移动k次等价于移动k%len次
思路一:计算出list长度
即通过一次遍历,找到列表的末节点同时,计算出列表的长度。根据列表的长度,计算k%len
,也就是最短等价移动次数。之后利用双指针,保证头指针和尾指针之间的距离始终为k,从而找到右边第k个节点。
public ListNode rotateRight2(ListNode head, int k) {
if(k==0 || head==null)
return head;
//get list length and last node
ListNode last = head;
int len = 1;
while(last.next != null){
last = last.next;
len++;
}
k = k%len;
if(k==0)
return head;
ListNode start = new ListNode(0);
start.next = head;
int count = len-k;
while(count > 0){
start = start.next;
count--;
}
last.next = head;
head = start.next;
start.next = null;
return head;
}
思路二:简单优化
其实在某些情况下,k的值并不一定比数组的长度大。这时候还计算数组的长度的话,反而降低了性能。这个时候,可以将遍历的过程和头指针的移动结合起来。如果头指针移动到结尾而k并不是等于0,则可以得知k大于列表长度,同时这个过程还可以得出列表的长度。如果k等于0时,头指针未移动到末尾,则可以继续头指针和尾指针的同时移动,知道头指针到达数组的最后一个元素。
代码如下:
public ListNode rotateRight(ListNode head, int k) {
if(head == null){
return null;
}
ListNode firstPointer = head;
int length = 0;
while(firstPointer!= null && k > 0){
k--;
firstPointer = firstPointer.next;
length++;
}
if(k == 0){
if(firstPointer == null){
return head;
}
ListNode secondPointer = head;
while(firstPointer != null && firstPointer.next!=null){
secondPointer = secondPointer.next;
firstPointer = firstPointer.next;
}
firstPointer.next = head;
ListNode result = secondPointer.next;
secondPointer.next = null;
return result;
}else{
return rotateRight(head, k%length);
}
}
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。