旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
思路+代码+注释:
public class SixOne {
public static void main(String[] args) {
ListNode head=new ListNode(1);
ListNode head2=new ListNode(2);
ListNode head3=new ListNode(3);
ListNode head4=new ListNode(4);
ListNode head5=new ListNode(5);
head.next=head2;
head2.next=head3;
head3.next=head4;
head4.next=head5;
head5.next=null;
rotateRight(head,2);
}
public static class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public static ListNode rotateRight(ListNode head, int k) {
/*
思路:定义一个方法,将链表每次向右移动一个位置
假设链表有n个节点,那么移动1个位置和移动n+1个位置的效果是等同的,所以需要先算出真正需要移动的位置个数m(就是k和链表个数n取模)
*/
//如果链表没有节点或者只有一个节点,直接返回head
if (head==null || head.next==null)
{
return head;
}
//需要移动位置,计算需要移动的位置个数
//计算链表节点个数count
int count=0;
ListNode curNode=head;
while (curNode!=null)
{
count++;
curNode=curNode.next;
}
int m=k%count;
for (int i = 0; i < m; i++) {
head=rotateRightOne(head);
}
return head;
}
private static ListNode rotateRightOne(ListNode head)
{
//记录尾节点
ListNode tail=null;
//记录尾节点前一个节点
ListNode beforeTail=null;
//记录当前节点
ListNode curNode=head;
//寻找尾节点和尾节点的前一个节点
while (curNode!=null)
{
if (curNode.next!=null)
{
beforeTail=curNode;
}else {
tail=curNode;
}
curNode=curNode.next;
}
//尾节点的下一个节点为当前head节点
tail.next=head;
//尾节点的前一个节点成为新的尾节点
beforeTail.next=null;
//尾节点成为新的head节点
head=tail;
//返回新的头节点
return head;
}
}