题目如下:
给定一个链表,旋转链表,将链表每个节点向右移动 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
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
来源:力扣(LeetCode)
以下是我给出的答案:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
/*如果旋转次数为0 或者 链表为空,或者链表长度为1(长度为1,
旋转多少次都是本体,顾直接返回即可),直接返回链表。*/
if(k < 0 || head == null || head.next == null )return head;
//最后一个节点
ListNode curr = head;
//倒数第二个节点
ListNode nNode = null;
int nodeLen;
//获取链表长度
nodeLen = getNodelens(head);
// 旋转次数初始为要求转的次数
int move = k;
/* 如果要旋转的次数大于链表长度,那么求余即可。eg: 链表长度为3 ,
旋转4次,那么我们实际上只需要对 旋转次数 求余 链表大小 即可,
即 4%3 =1 旋转一次即可。因为中间的一圈实在没必要。转一圈跟没转一样。
考虑到效率问题,顾这里求余即可*/
if(move >= nodeLen) move = move % nodeLen ;
// 当旋转次数不为0
while(move > 0){
//每次旋转都需要改变倒数第一和倒数第二个节点。
ListNode array[] = changeNode(head);
curr = array[0];
nNode = array[1];
curr.next = head;
nNode.next = null;
head = curr;
move--;
}
return head;
}
// 获取链表长度
private int getNodelens(ListNode head){
int i = 0;
while(head != null){
i++;
head = head.next;
}
return i;
}
//获取最后倒数第一个节点和倒数第二个节点
private ListNode[] changeNode(ListNode head){
ListNode curr = head;
ListNode nNode = null;
ListNode []arry = new ListNode[2];
// 如果没有到达表尾
while(curr.next != null){
nNode = curr;
curr = curr.next;
}
arry[0] = curr;
arry[1] = nNode;
return arry;
}
}
运行结果:
总结:
- 由于之前数据结构的基础功力还算扎实,所以编写此题并没有很大的困难。本身该题目也就不算难,所以更是如鱼得水了。特此总结以下。2019.11