题目描述:给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
思路一:刚开始想到使用队列,将这个链表数据存储进去,进行k次出队入队操作,然后重新建立一个新的链表,并返回。(需要注意如果k的值大于链表长度,就会过多的重复队列操作,所以需要简化k)
import java.util.ArrayDeque;
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head == null || head.next == null) {
return head;
}
ArrayDeque<Integer> queue = new ArrayDeque<>();
ListNode cur = head;
int count = 0;
while(cur != null) {
queue.addFirst(cur.val);
cur = cur.next;
count++;
}
if(k >= count) k %= count;
for(int i = 0;i < k;i++) {
int temp = queue.remove();
queue.add(temp);
}
ListNode pro = new ListNode(0);
ListNode pre = pro;
while(!queue.isEmpty()) {
cur = new ListNode(queue.removeLast());
pre.next = cur;
pre = cur;
}
cur.next = null;
return pro.next;
}
}
但是这种思路太耗时,因为创建节点过于耗时了。
思路二:查看题解之后,可以将链表闭合,然后确定新的表头(n-k)和表尾(n-k-1),断掉表头表尾之间的连接,返回新的链表,这样就可以减少创建节点的时间。
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head == null || head.next == null) {
return head;
}
// 将链表闭环
ListNode oldTail = head;
int n = 1;
while(oldTail.next != null) {
++n;
oldTail = oldTail.next;
}
oldTail.next = head;
// 这里为了防止重复移动,当k大于n时,取余
if(k >= n) k %= n;
// 新的链表头为n-k,链表尾为n-k-1
ListNode newTail = head;
for(int i = 0;i < n-k-1;i++)
newTail = newTail.next;
ListNode newHead = newTail.next;
// 断开链表
newTail.next = null;
return newHead;
}
}