写链表代码技巧:
- 技巧一:理解指针或引用的含义
- 技巧二:警惕指针丢失和内存泄漏
- 技巧三:利用哨兵简化实现难度
- 技巧四:重点留意边界条件处理
- 技巧五:举例画图,辅助思考
- 技巧六:多写多练,没有捷径
问题描述:给定一个带有头结点 head
的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
方法:快慢指针
复杂度分析:
- 时间复杂度:O(N)O(N)O(N),其中 NNN 是给定链表的结点数目。
- 空间复杂度:O(1)O(1)O(1),只需要常数空间存放 slow 和 fast 两个指针。
代码:
public class MiddleNode {
/**
* 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。
* 如果有两个中间结点,则返回第二个中间结点。
* @param head
* @return
*/
public ListNode middleNode(ListNode head) {
ListNode slowPoint = head;
ListNode fastPoint = head;
while (fastPoint != null && fastPoint.next != null) {
fastPoint = fastPoint.next.next;
slowPoint = slowPoint.next;
}
return slowPoint;
}
public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode next1 = new ListNode(2);
ListNode next2 = new ListNode(3);
ListNode next3 = new ListNode(4);
ListNode next4 = new ListNode(5);
ListNode next5 = new ListNode(6);
head.next = next1;
next1.next = next2;
next2.next = next3;
next3.next = next4;
next4.next = next5;
ListNode listNode = new MiddleNode().middleNode(head);
while (listNode != null) {
System.out.println(listNode.val);
listNode = listNode.next;
}
}
}
/**
* @Description: Definition for singly-linked list.
*/
public class ListNode {
int val;
ListNode next;
ListNode(int val){
this.val = val;
}
}