题目主要信息
给定链表的头节点,旋转链表,将链表每个节点往右移动 k 个位置,原链表后 k 个位置的节点则依次移动到链表头。
即,例如链表 : 1->2->3->4->5 k=2 则返回链表 4->5->1->2->3
方法一:直接求解
具体方法
按照下面的步骤处理即可
- 1、求出链表的长度
- 2、将链表闭合
- 3、求出旋转后的链表的首节点
- 4、断链操作
代码实现
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode rotateLinkedList (ListNode head, int k) {
// write code here
if(head == null)
return null;
int len = 1;
// 求出链表长度
ListNode temp = head;
while(temp.next !=null)
{
len++;
temp = temp.next;
}
//旋转后链表的首节点
int p = len - k % len;
temp.next = head;
//找到首节点
while(p>0){
temp = temp.next;
p--;
}
//断链
ListNode res = temp.next;
temp.next = null;
return res;
}
}
复杂度分析
-
时间复杂度:,遍历一次链表
-
空间复杂度:,我们只需要常数的空间存储若干变量。
方法二:双指针
具体方法
因为k有可能大于链表长度,所以首先获取一下链表长度len。如果k % len == 0,等于不用旋转,直接返回头结点。否则:
- 快指针先走k步,然后慢指针和快指针一起走。
- 快指针走到链表尾部时,慢指针刚好走到旋转链表的尾部。把快指针指向的节点连到原链表头部,慢指针指向的节点断开和下一节点的联系。
- 返回结束时慢指针指向节点的下一节点。
代码实现
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode rotateLinkedList (ListNode head, int k) {
//特殊情况直接返回
if(head == null || k == 0){
return head;
}
ListNode temp = head;
ListNode fast = head;
ListNode slow = head;
int len = 0;
//求链表长度
while(head != null){
head = head.next;
len++;
}
if(k % len == 0){
return temp;
}
//快指针先走k步
while((k % len) > 0){
k--;
fast = fast.next;
}
//两个一起走
while(fast.next != null){
fast = fast.next;
slow = slow.next;
}
ListNode result = slow.next;
slow.next = null;
fast.next = temp;
return result;
}
}
复杂度分析
-
时间复杂度:,遍历一次链表
-
空间复杂度:,我们只需要常数的空间存储若干变量。