2020年3月23日。
题出处:点击此处
考点:链表的遍历,快慢指针的运用。
题解:
1.本道题要求删除链表的中间节点。很明显,最暴力的解法就是二次遍历。
时间复杂度为O(n),空间复杂度为O(1)
这是只要学过链表的人,都应该掌握的。
2.本道题应该学会的一种思想为快慢指针。
即在链表中存在双指针,一快一慢。
在这道题中快指针一次走两步,而慢指针一次走一步。
为什么这样能work?
因为当快指针到最后的时候,比慢指针多走的路径就是慢指针的一倍。
于是加起来得到就是两倍。(无论链表为奇数还是偶数)
虽然这样依然是O(n)的时间复杂度,可我们思考一下就知道,这样算肯定比二次遍历要优化。
本题的代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
//注意跳出条件。
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
自己一开始没想到快慢指针的暴力二次遍历法(不建议参考)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
int num = 0;
ListNode temp = head;
while(temp != null){
num++;
temp = temp.next;
}
int ans = num / 2 + 1;
temp = head;
for(int i = 1; i < ans; i++){
temp = temp.next;
}
return temp;
}
}