题目
给一个链表头节点,旋转链表,将链表每个节点向右边移动k个位置。
分析一波
k:代表向右移动的位数;
n: 指的是链表的长度,链表有几位节点;
因为题目并没有告诉k和n的关系,也就是说没说k会比n小,所以,k的数字可能会很大;
因此,为了不必要的多余操作转多余的圈,我们用对k取余的方式;
对k取余。多余的圈数去掉;
k是从后往前找;
思路
先把链表最后一个节点和头节点head连接起来,
围成一个圈,然后找到k (是从后面数是k,从前面数就是n-k+1,n是链表的总节数,k是题目中的向右移动几位)的位置,
分开,也就是从头数到第n-k+1的位置断开,也就是它的后面的节点设置为null,
把之前后面的节点指向头节点就ok啦。
将链表形成一个圈,
找到K的位置,
然后将它下一个节点设置为null,
再将原先的下一个节点指向head,
就是断开k之前的,之后的设置为头节点。
实践,上代码
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var rotateRight = function(head, k) {
if(!head) return head;
let p=head,n=1;
while(p.next){
p=p.next;
n++;
}
//这里就算是把链表围成一个圈了。
p.next=head;
k%=n,k=n-k;
while(k--) p=p.next;
head=p.next;
p.next=null;
return head;
};
专门设置个n来计算链表的长度,这点很重要。
开始是把链表围成一个圈了。
最后的k是(也就是第二个运算中的k,第一个运算的k还是正着数的k的位置)计算正着数k的位置,这里比较巧妙使用对k%n去余,去掉多余的圈数,因为并没有告诉k个链表长度之间的关系,有可能k非常大,然后又比如k=3n+1.这里计算后面的1就用取余。
p.next设置为头,是head=p.next而不是p.next=head;
返回的是head不是p
就是先计算出链表的长度然后围成一个圈,然后计算出链表正着数k的位置,断掉k后面的节点,然后把k位置之前后面节点改为头部节点。