参考WalkingInTheWind的博客
Let’s Start //从最简单的开始
链表声明
|
|
Index
|
|
1. 求单链表中结点的个数
遍历整个链表就好, O(n)
|
|
2. 将单链表反转
方法1
用3个指针实现反转,in-place,时间复杂度为O(n), 空间O(1)。
定义p, q, r指针,p = head, q = head->next, r = q->next;
- p指向null,旧链表的头为新链表的尾;
- q指向p(新链表的尾)
- p = q, q = r; 然后下一轮循环(r=q->next),参考代码如下:
|
|
方法2
从图上观察,方法是:对于一条链表,从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,(N-1)次这样的操作结束之后将第1个节点挪到新表的表尾即可。
|
|
3. 查找单链表中的倒数第K个结点(k > 0)
最普遍的方法是,先统计单链表中结点的个数,然后再找到第(n-k)个结点。注意链表为空,k为0,k为1,k大于链表中节点个数时的情况。时间复杂度为O(n)。也可以用双指针法,一个runner,一个chaser
|
|
4. 查找单链表的中间结点
依然用双指针法,代码略。
5. 从尾到头打印单链表
用栈来实现,先进后出。要么自己维护栈,要么用递归,注意链表为空的情况,还有base case. 复杂度O(n)
|
|
6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序
类似于merge sort,用Divide conque,注意两个链表为空,或一个为空的情况。O(max(len1, len2))
7. 判断一个单链表中是否有环
用双指针法,如果相遇则有环,否则无环。如果要找出环的开始点,则相遇后把chaser放回head,两个指针每次走一步,相遇节点为loop起始点。
代码略。
8. 如果要遍历链表,可以考虑在head前加一个dummy node,并且检查边界条件防治数组越界(切记,出现好多次了;( )
比如swap nodes这一题,可以swap(p->val, p->next->val),注意数组不要越界,也可以考虑在head前面加dummy node.
|
|
注意:一个重复周期内涉及的链表先保存下一个变量,不然->next会timeout limit。并且设定初始条件链表元素数目是(head == NULL)还是(head == NULL || head->next == NULL)。
Deploy to remote sites
|
|
More info: Deployment