1. 题目描述(中等难度)
思路:
- 先得到链表的节点数,即节点长度
- 再计算旋转点是正数的第几个数。
- 计算新的k值,忽略重复旋转的次数
- 如果最后k==0,说明无需旋转,直接输出。
- 设置pre指针。pre的next指向需要旋转的链表的第一个节点。将他们整体移到首部
问题:我的解法太过复杂,在计算链表长度时,可以保存链表的尾指针,这样在第二遍循环时,就不用寻找了。
1 | /** |
2 | * Definition for singly-linked list. |
3 | * public class ListNode { |
4 | * int val; |
5 | * ListNode next; |
6 | * ListNode(int x) { val = x; } |
7 | * } |
8 | */ |
9 | class Solution { |
10 | public ListNode rotateRight(ListNode head, int k) { |
11 | if(head==null)return null;//如果链表为空 |
12 | //先计算节点数量 |
13 | ListNode l1=head; |
14 | int dotnum=0; |
15 | while(l1!=null) |
16 | { |
17 | dotnum++; |
18 | l1=l1.next; |
19 | } |
20 | //倒转 |
21 | if(k>=dotnum) |
22 | k=k%dotnum; |
23 | if(k==0) return head//0属于特判,相当于没有反转,之前没有考虑到 |
24 | ListNode pre=head; |
25 | int rotalteindex=dotnum-k;// 计算可得,pre的下一个节点就是要倒转的序列 |
26 | while(pre!=null) |
27 | { |
28 | if(rotalteindex==1) |
29 | { |
30 | ListNode ro=pre.next; |
31 | pre.next=null; |
32 | pre=ro; |
33 | while(ro.next!=null)//找到旋转链表的尾部指针,使其直接指向总链表的head |
34 | ro=ro.next; |
35 | ro.next=head; |
36 | head=pre;//更新head |
37 | break; |
38 | } |
39 | pre=pre.next; |
40 | rotalteindex--; |
41 | } |
42 | return head; |
43 | } |
44 | } |
- 时间复杂度:O(n)
- 空间复杂度:O(1)
解决问题:1
/**
2
* Definition for singly-linked list.
3
* public class ListNode {
4
* int val;
5
* ListNode next;
6
* ListNode(int x) { val = x; }
7
* }
8
*/
9
class Solution {
10
public ListNode rotateRight(ListNode head, int k) {
11
if(head==null)return null;
12
//先计算节点数量
13
ListNode l1=head;
14
ListNode tail=l1;
15
int dotnum=0;
16
while(l1!=null)
17
{
18
dotnum++;
19
tail=l1;//记录尾指针
20
l1=l1.next;
21
22
}
23
//倒转
24
if(k>=dotnum)
25
k=k%dotnum;
26
if(k==0) return head;//0属于特判,相当于没有反转,之前没有考虑到
27
ListNode pre=head;
28
int rotalteindex=dotnum-k;// 计算可得,pre的下一个节点就是要倒转的序列
29
while(pre!=null)
30
{
31
if(rotalteindex==1)
32
{
33
ListNode ro=pre.next;
34
pre.next=null;
35
tail.next=head;//直接使用尾指针
36
head=ro;
37
break;
38
}
39
pre=pre.next;
40
rotalteindex--;
41
}
42
return head;
43
}
44
}
3方法二:
这道题不能直接使用快慢指针,不求链表总长,因为k是一个任意大的数,存在重复旋转的问题。
如果k<=链表总长,那么可以直接用快慢指针1
class Solution {
2
public ListNode rotateRight(ListNode head, int k) {
3
if(head==null)return null;
4
//利用快慢指针
5
ListNode first=head;
6
ListNode second=head;
7
for(int i=0;i<k;i++)
8
first=first.next;
9
while(first.next!=null)//使快指针最后指向尾节点
10
{
11
first=first.next;
12
second=second.next;
13
}
14
ListNode newhead=second.next;
15
second.next=null;
16
first.next=head;
17
head=newhead;
18
return newhead;
19
}
20
}
4 总结
对于针对链表中倒数第n个节点的问题,可以使用快慢指针或先求链表总长len,在计算节点正数的顺序。使用第一中方法的前提是k<=len.