鏈表的中間結點
題目
給定一個帶有頭結點 head 的非空單鏈表,返回鏈表的中間結點。
如果有兩個中間結點,則返回第二個中間結點。
示例 1:
輸入:[1,2,3,4,5]
輸出:此列表中的結點 3 (序列化形式:[3,4,5])
返回的結點值為 3 。 (測評系統對該結點序列化表述是 [3,4,5])。
注意,我們返回了一個 ListNode 類型的對象 ans,這樣:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:
輸入:[1,2,3,4,5,6]
輸出:此列表中的結點 4 (序列化形式:[4,5,6])
由于該列表有兩個中間結點,值分別為 3 和 4,我們返回第二個結點。
提示:
給定鏈表的結點數介于 1 和 100 之間。
有三種思路
- 思路一: 利用快慢指針
- 思路二:利用數組
- 思路三: 利用鏈表
Java實現
/**
* 利用快慢指針思想
* 用兩個指針 slow 與 fast 一起遍歷鏈表。slow 一次走一步,fast 一次走兩步。
* 那么當 fast 到達鏈表的末尾時,slow 必然位于中間。
*/
public ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
/**
* 利用數組解決
* 對鏈表進行遍歷,同時將遍歷到的元素依次放入數組 A 中。如果我們遍歷到了 N 個元素,
* 那么鏈表以及數組的長度也為 N,對應的中間節點即為 A[N/2]。
*/
public ListNode middleNode2(ListNode head) {
ListNode[] Array = new ListNode[100];
int num = 0;
while (head != null) {
Array[num++] = head;
head = head.next;
}
return Array[num >> 1];
}
// 使用鏈表知識
public ListNode middleNode1(ListNode head) {
ListNode tempHead = head;
int num = 1;
while (tempHead.next != null) {
tempHead = tempHead.next;
num ++;
}
int index = (num >> 1) + 1;
ListNode node = head;
for (int i = 0; i < index - 1 ; i++) {
node = node.next;
}
return node;
}
Swift實現
/**
利用鏈表
*/
func middleNode(_ head: ListNode?) -> ListNode? {
var temp = head
var nums = 0
while temp != nil {
temp = temp?.next
nums = nums + 1
}
var first = head
let index = nums >> 1
var i = 0
while i < index {
first = first?.next
i = i + 1
}
return first
}
/***
利用快慢指針思想解決
*/
func middleNode1(_ head: ListNode?) -> ListNode? {
var slow = head
var fast = head
while fast != nil, fast?.next != nil {
slow = slow?.next
fast = fast?.next?.next
}
return slow
}
/**
利用數組
*/
func middleNode2(_ head: ListNode?) -> ListNode? {
var array:[ListNode] = [ListNode]()
var temHead = head
var num: Int = 0
while temHead != nil {
array.append(temHead!)
temHead = temHead?.next
num = num + 1
}
return array[num >> 1]
}
```