Java演算法面試題(002) 如何通過一次迭代找到LinkedList的中間元素
宣告:本文為本博主翻譯,未經允許,嚴禁轉載!
簡介
Java和非Java程式設計師在電話面試中經常被問及如何僅一次遍歷查詢到LinkedList的中間元素。這個問題類似於檢查迴文或者計算階乘,面試官有時也會要求編寫程式碼。為了回答這個問題,候選人必須熟悉LinkedList資料結構,即在單LinkedList的情況下,連結串列的每個節點都包含資料和指標,它是下一個連結串列節點的地址,單連結串列的最後一個元素指向null。由於為了找到連結串列的中間元素,你需要找到LinkedList的長度,這需要對連結串列節點進行計數直到最後一個元素為止。讓這個資料結構面試問題有趣的是,你需要在一次遍歷中找到LinkedList的中間元素,而你不知道LinkedList的長度。這是考驗候選人邏輯能力的地方:他是否熟悉空間和時間的權衡等等。
如果你仔細想想,你可以通過使用兩個指標來解決這個問題,就像我在上一篇關於如何在Java中查詢單一連結串列的長度的文章中提到的那樣。通過使用兩個指標,其中一個每次迭代增一,另外一個每兩次迭代增。當第一個指標指向連結串列的末尾時,第二個指標將指向連結串列的中間節點。
實際上,這兩個指標方法可以解決多個相似的問題,如何在一個迭代中從連結串列中找到倒數第3個元素,或者如何在連結串列中找到倒數第N個元素。在這個Java程式設計教程中,我們將看到一個Java程式,它在一個迭代中查詢連結列表的中間元素。
這裡是完整的Java程式來查詢Java中的連結串列的中間節點。記住LinkedList類是我們的自定義類,不要把這個類與Java中流行的Collection類java.util.LinkedList混淆。在這個Java程式中,我們的類LinkedList表示一個包含節點集合並具有頭部和尾部的連結串列資料結構。每個節點都包含資料和地址部分。 LinkedListTest類的主要方法是用來模擬問題的,在這裡我們建立了Linked List,並在其上新增了一些元素,然後遍歷它們在Java中一次遍歷連結列表的中間元素。
通過一次LinkedList迭代查詢中間元素的Java程式
/**
* Java program to find middle element of linked list in one pass. In order to
* find middle element of linked list we need to find length first but since we
* can only traverse linked list one time, we will use two pointers one which we
* will increment on each iteration while other which will be incremented every
* second iteration. so when first pointer will point to the end of linked list,
* second will be pointing to the middle element of linked list
*
* @author
*/
public class LinkedListTest {
public static void main(String[] args) {
// creating LinkedList with 5 elements including head
LinkedList list = new LinkedList();
list.add(new LinkedList.Node("1"));
list.add(new LinkedList.Node("2"));
list.add(new LinkedList.Node("3"));
list.add(new LinkedList.Node("4"));
list.add(new LinkedList.Node("5"));
LinkedList.Node head = list.head();
// finding middle element of LinkedList in a single pass
LinkedList.Node current = head;
LinkedList.Node middle = head;
int length = 0;
while (current.next() != null) {
length++;
if (length % 2 == 0) {
middle = middle.next();
}
current = current.next();
}
length++;
System.out.println("length of LinkedList: " + length);
System.out.println("middle element of LinkedList : " + middle);
}
}
class LinkedList {
private Node head;
private Node tail;
/**
* Constructs an empty list
*/
public LinkedList() {
head = null;
tail = null;
}
public Node head() {
return head;
}
public void add(Node node) {
if (head == null) {
head = node;
tail = node;
return;
}
tail.next = node;
tail = node;
}
public static class Node {
private Node next;
private String data;
public Node(String data) {
this.data = data;
}
public String data() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Node next() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public String toString() {
return this.data;
}
}
}
原文連結
How to find middle element of LinkedList in Java in one pass in Java
譯者備註
1. 譯文中實現與原實現有些差異,原文中在連結串列初始化時自動建立了一個無關節點,相關實現也不容易理解,這塊在上文中譯者進行了優化,感興趣的可以對比一下原文的實現。
2. 你應該搞清楚迭代一次是什麼意思。如果面試官說你不能迴圈兩次而只需要使用一個迴圈,那麼你可以使用兩個指標來解決這個問題。在兩個指標方法中,你有兩個指標,快指標和慢指標。在每個步驟中,快速指標移動兩個節點,而慢速指標僅移動一個節點。所以,當快速指標指向最後一個節點,即下一個節點為空時,慢速指標將指向連結串列的中間節點。
3. 這裡再舉一個類似的案例,可以使用本文的演算法解決: 例如,假設你有一個連結串列a1 - > a2 - > ... - > an - > b1 - > b2 - > ... - > bn,將其重新排列為a1→b1→a2→b2→b→a→bn。你不知道連結串列的長度(但是你要知道長度是偶數)。你可以有一個指標p1(快速指標)為每次移動兩個元素,而p2(慢速指標)每次移動一個元素。當p1到達連結串列的末尾時,p2將處於中點。然後,將p1移回前面並開始組織的元素。在每次迭代中,p2選擇一個元素並將其插入到p1之後。
相關文章
- 如何在Java中一次性查詢Java中連結串列的中間元素Java
- Java面試 | 002Java面試
- Java中在迭代時新增元素的3種方法Java
- 不用for迭代 --手工訪問迭代器中的元素.
- Java中LinkedListJava
- 【Java面試題】54 去掉一個Vector集合中重複的元素Java面試題
- 如何通過自學找到一份開發的工作?
- LeetCode高頻演算法面試題 - 002 - 兩數相加LeetCode演算法面試題
- 找到兩個陣列中的公共元素陣列
- Java集合面試題(03) Java中HashMap和HashTable之間區別Java面試題HashMap
- IT人如何找到自己的時間?
- 【面試】如何找到迷宮出口面試
- java Count如何計算流中的元素Java
- java中的List介面(ArrayList、Vector、LinkedList)Java
- 女生在求職面試過程中,如何巧妙回答面試官的尷尬問題求職面試
- js通過元素的class屬性獲取元素JS
- java面試一日一題:java中垃圾回收演算法有哪些Java面試演算法
- 【Java 8 新特性】Java Stream 通過skip()方法跳過前N個子元素Java
- 如何順利通過程式設計面試程式設計面試
- 如何通過面試第一關【簡歷】面試
- Java——深入瞭解Java中的迭代器Java
- 記一次騰訊面試:程式之間究竟有哪些通訊方式?如何通訊? ---- 告別死記硬背面試
- Java演算法面試題(009) 毒酒問題Java演算法面試題
- 通過面試題,讓我們來了解Collection面試題
- T面試題:程式間的通訊方式有哪幾種?面試題
- Java中ArrayList和LinkedList區別Java
- Java求職者如何提高面試的透過率?Java求職面試
- 從面試題中學演算法(1)--雜湊表查詢字串中第一次僅出現一次的字母面試題演算法字串
- 找到的比較好的工作面試題筆試題面試題筆試
- 通過 find 命令找到你要找的東西
- Java執行緒面試題(03) Java中的volatile如何工作? Java中的volatile關鍵字示例Java執行緒面試題
- LinkedList 新增元素原始碼解析原始碼
- 遍歷聚合物件中的元素——迭代器模式(四)物件模式
- 遍歷聚合物件中的元素——迭代器模式(三)物件模式
- 一種通過程式設計面試的演算法 - malisper.me程式設計面試演算法Lisp
- 閱讀原始碼,通過LinkedList回顧基礎原始碼
- 程式設計師如何一次通過軟考?程式設計師
- 如何通過binlog 輕鬆的找到沒有及時提交的事物(infobin工具)