題目地址:https://leetcode-cn.com/problems/rotate-list/
題目:
給定一個(gè)鏈表,旋轉(zhuǎn)鏈表萎庭,將鏈表每個(gè)節(jié)點(diǎn)向右移動 k 個(gè)位置趴俘,其中 k 是非負(fù)數(shù)忌傻。
示例 1:
輸入: 1->2->3->4->5->NULL, k = 2
輸出: 4->5->1->2->3->NULL
解釋:
向右旋轉(zhuǎn) 1 步: 5->1->2->3->4->NULL
向右旋轉(zhuǎn) 2 步: 4->5->1->2->3->NULL
試題分析:
這道題如果前期沒有準(zhǔn)備過直接寫很容易漏掉一些異常處理和移位超出鏈表長度的處理屁置,總體算法思路是先找到需要旋轉(zhuǎn)的位置,這里有一個(gè)點(diǎn)需要注意下朗若,就是移動的位數(shù)k有可能會大于鏈表總長度恼五,所以需要先遍歷出鏈表總長度,然后總長度減去k后按照總長度取模 length-k%length
遍歷鏈表找到要旋轉(zhuǎn)的節(jié)點(diǎn)位置哭懈,然后定義一個(gè)旋轉(zhuǎn)后的鏈表頭指向這個(gè)節(jié)點(diǎn)的next灾馒,然后讓舊鏈表的尾節(jié)點(diǎn)和舊鏈表的頭節(jié)點(diǎn)對接,這樣就完成了旋轉(zhuǎn)遣总。
代碼:
public ListNode rotateRight(ListNode head, int k) {
if(head==null || k==0 ||head.next==null){
return head;
}
ListNode p = head;
//遍歷出鏈表長度
int length = 0;
ListNode tail = head;
for(;tail.next!=null;tail=tail.next){
length++;
}
length++;
//找到需要反轉(zhuǎn)的節(jié)點(diǎn)的前置節(jié)點(diǎn)
for(int i=1;i<length-k%length;i++){
p = p.next;
}
//如果反轉(zhuǎn)節(jié)點(diǎn)的前置節(jié)點(diǎn)是最后一個(gè)節(jié)點(diǎn)則不需要反轉(zhuǎn)直接返回原頭節(jié)點(diǎn)
if(p.next==null){
return head;
}else {
//新翻轉(zhuǎn)后的頭節(jié)點(diǎn)指向剛才遍歷出的反轉(zhuǎn)節(jié)點(diǎn)的前置節(jié)點(diǎn)的next節(jié)點(diǎn)
ListNode newHead = p.next;
//尾節(jié)點(diǎn)next指向原h(huán)ead節(jié)點(diǎn)
tail.next = head;
p.next = null;
return newHead;
}
}
源碼路徑:com.monkey01.linkedlist.RotateList_61
配套測試代碼路徑:test目錄com.monkey01.linkedlist.RotateList_61Test