互聯網大廠算法面試題之旋轉鏈表


 

今天帶來一道來自互聯網大廠(字節、騰訊、微軟、蘋果等) 面試題 Leetcode 61. 旋轉鏈表,提供 "虛擬頭節點 + 雙指針" 的解題思路,采用 "動圖" 的方式進行層層剖析,供大家參考,希望對大家無論是刷題還是面試都有所幫助。

61. 旋轉鏈表

描述

給你一個鏈表的頭節點 head ,旋轉鏈表,將鏈表每個節點向右移動 k 個位置。

解題思路

思考

考慮以下幾種情況:

特殊情況

  1. 鏈表為空或只有一個節點;
  2. k 的值為 0 或者為鏈表長度 L 的整數倍(N > 0)。

一般情況

  1. 鏈表至少有兩個節點且 k 既不等於 0 也不等於 L 的整數倍。

思路

  • 特殊情況
  1. 鏈表為空或只有一個節點,只要返回頭節點即可;
  2. 判斷 k == 0,如果等於 0,則直接返回頭節點,否則求鏈表長度 L,再判斷 k == NL,如果等於,也可直接返回。
  • 一般情況
  1. 采用 虛擬頭節點 + 雙指針 的方法,具體如下栗子分析。
舉栗

以鏈表 1->2->3->4->5,k = 2 為栗子,如下圖所示。

增加虛擬頭節點,設置兩根快慢指針 fast/slow 指向它;

先讓快指針 fast 向前移動 k 步,慢指針 slow 保持不動; 

快慢指針 fast/slow 同時向前移動,直至快指針指向尾節點;

讓快指針 fast 指向的節點指向鏈表的頭節點; 

將慢指針 slow 指向的節點的下一節點設置為新鏈表的頭節點; 

將慢指針 slow 指向的節點設置為新鏈表的尾節點 slow->next = null; 

旋轉原鏈表后得到新鏈表。 

 完整動圖

反思

  1. 如何找到旋轉之后得到的新鏈表的頭節點?

采用 雙指針 中的 快慢指針

  1. 設置虛擬頭節點的作用?

本題設置 虛擬頭節點 的作用是找到 新鏈表的頭節點和尾節點。通過 快慢指針 去尋找。

Show me the Code

C++

 1 ListNode* rotateRight(ListNode* head, int k) {
 2     /*  特殊情況判斷  */
 3     if (head == nullptr || head->next == nullptr || k == 0) {
 4         return head;
 5     }
 6 
 7     /*  增加虛擬頭節點  */
 8     ListNode* dummy = new ListNode(0);
 9     dummy->next = head;
10 
11     /*  獲取鏈表長度  */
12     int len = 0;
13     for (ListNode* node = head; node != nullptr; node = node->next) {
14         len++;
15     }
16 
17     k %= len;
18     /*  判斷 k 是否是 len 的整數倍  */
19     if (k == 0) {
20         return head;
21     }
22 
23     /*  獲取新鏈表的頭尾節點  */
24     ListNode *fast = dummy, *slow = dummy;
25     for (int i = 0; i < k; ++i) {
26         fast = fast->next;
27     } 
28     while (fast->next != nullptr) {
29         fast = fast->next;
30         slow = slow->next;   
31     }        
32     fast->next = head; 
33     head = slow->next; 
34     slow->next = nullptr;
35 
36     /*  釋放虛擬頭節點  */
37     delete dummy;
38     
39     return head;
40 }
View Code

java

 1 ListNode rotateRight(ListNode head, int k) {
 2     if (k == 0 || head == null || head.next == null) {
 3         return head;
 4     }
 5 
 6     ListNode dummy = new ListNode(0);
 7     dummy.next = head;
 8 
 9     int len = 0;
10     for (ListNode node = head; node != null; node = node.next) {
11         len++;
12     }     
13 
14     k %= len;
15     if (k == 0) {
16         return head;
17     }
18 
19     ListNode fast = dummy, slow = dummy;
20     for (int i = 0; i < k; ++i) {
21         fast = fast.next;
22     } 
23     while (fast.next != null) {
24         fast = fast.next;
25         slow = slow.next;   
26     }        
27     fast.next = head; 
28     head = slow.next; 
29     slow.next = null;
30 
31     return head;
32 }
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM