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*/9class Solution {10public ListNode rotateRight(ListNode head, int k) {11if(head==null)return null;12//先计算节点数量13ListNode l1=head;14ListNode tail=l1;15int dotnum=0;16while(l1!=null)17{18dotnum++;19tail=l1;//记录尾指针20l1=l1.next;2122}23//倒转24if(k>=dotnum)25k=k%dotnum;26if(k==0) return head;//0属于特判,相当于没有反转,之前没有考虑到27ListNode pre=head;28int rotalteindex=dotnum-k;// 计算可得,pre的下一个节点就是要倒转的序列29while(pre!=null)30{31if(rotalteindex==1)32{33ListNode ro=pre.next;34pre.next=null;35tail.next=head;//直接使用尾指针36head=ro;37break;38}39pre=pre.next;40rotalteindex--;41}42return head;43}44}3方法二:
这道题不能直接使用快慢指针,不求链表总长,因为k是一个任意大的数,存在重复旋转的问题。
如果k<=链表总长,那么可以直接用快慢指针1class Solution {2public ListNode rotateRight(ListNode head, int k) {3if(head==null)return null;4//利用快慢指针5ListNode first=head;6ListNode second=head;7for(int i=0;i<k;i++)8first=first.next;9while(first.next!=null)//使快指针最后指向尾节点10{11first=first.next;12second=second.next;13}14ListNode newhead=second.next;15second.next=null;16first.next=head;17head=newhead;18return newhead;19}20}4 总结
对于针对链表中倒数第n个节点的问题,可以使用快慢指针或先求链表总长len,在计算节点正数的顺序。使用第一中方法的前提是k<=len.