旋转问题
//向右旋转链表
//是否可以采用递归
//时间复杂度为O(n^2) 超时
//超过80%的用户
//进行了优化
public ListNode rotateRight(ListNode head, int k) {
if(head==null||head.next==null||k==0) return head;
//求链表的长度 链表长度为n的话 只需要旋转 k%n次即可
ListNode temp = head;
int size = 0;
while(temp!=null){
size++;
temp=temp.next;
}
//左了优化
k=k%size;
//亚节点
ListNode dummyHead = new ListNode(-1);
dummyHead.next=head;
//时间复杂度为O(n^2)
for(int i=0;i<k;i++){
//找到此时的尾部节点
ListNode pre = dummyHead;
ListNode cur = dummyHead.next;
//找到尾部接地那
while(cur.next!=null){
pre=pre.next;
cur = cur.next;
}
pre.next=null;
cur.next=dummyHead.next;
dummyHead.next=cur;
}
return dummyHead.next;
}
代码优化
package com.zj.CLinkedList;
/**
* @Auther Jian Zhou
* @Date 2020/7/25
*/
public class Problem61 {
//对链表进行旋转
public ListNode rotateRight(ListNode head, int k) {
if(head==null) return null;
//获取链表的长度
int length = length(head);
//实际需要享有面移动的次数
k = k%length;
//不需要移动
if(k==0) return head;
//向右面移动k个步 就是讲倒数第k个开始的元素插入到链表的头部
ListNode lastPrevK = getLast(head,k+1);//获取倒数第k+1个节点
ListNode lastK =lastPrevK.next;
//获取倒数第一个节点
ListNode last = getLast(head,1);
lastPrevK.next=null;
//将倒数第一个节点的下一个节点设置为head[lastK,LAST]--->head
last.next=head;
return lastK;
}
/**
* 获取倒数第k个元素
* @param head
* @param k
* @return
*/
public ListNode getLast(ListNode head,int k){
if(head==null) return null;
ListNode quick = head;
ListNode slow = head;
for(int i=1;i<k;i++){
quick=quick.next;
}
while (quick.next!=null){
quick=quick.next;
slow=slow.next;
}
return slow;
}
/**
* 获取链表的长度
* @param head
* @return
*/
public int length(ListNode head){
if(head==null) return 0;
ListNode temp = head;
int size = 0;
while (temp!=null){
size++;
temp=temp.next;
}
return size;
}
public static void main(String[] args) {
int[] nums = {1,2,3,4,5};
ListNode head = new ListNode(nums);
Problem61 problem61 = new Problem61();
System.out.println(problem61.getLast(head, 2));
ListNode listNode = problem61.rotateRight(head, 3);
System.out.println(listNode);
}
}