昨天下午面试,被问到如何用单向列表实现O(1)增删。当时没想出来,事后想起自己曾见过将链表节点存入字典的操作。字典的查询不就是O(1)嘛。
但怎么通过这种方式对链表进行增删呢?
一种思路是改成双向链表实现。这里暂不讨论。
第二种思路是字典的key存x节点的值,key对应的value则存x的亲节点w。但这样就需要加一个虚拟头节点以获取真实的头节点,并且在增删节点的时候有些复杂。这其实是借助字典变相实现双链表
对于w->x->y->z
创建node(v),v.next = w
即(v)->w->x->y->z
维护两个指针head=v,tail=z
dict = {w.value: v, x.value: w, y.value: x, z.value: y}
将x移到尾部:
1.跟据x.value找到w节点
2.w.next获取x节点
2.w.next.next获取y节点
3.跟据y.value修改字典键值对{y.value: x}为{y.value: w},且令w.next = y
4.修改字典键值对{x.value: w}为{x.value: tail},且令tail.next = x
5.令tail=x
第三种方法是在网上找到的,思路比较新奇——直接修改节点的值,相较而言也更简单。
对于w(w.value)->x(x.value)->y(y.value)->z(z.value)
维护两个指针head=w,tail=z
dict = {w.value: w, x.value: x, y.value: y, z.value: z}
将x移到尾部:
1.跟据x.value找到x节点
2.x.next获取y节点
2.暂存tem = x.value,令x.value = y.value
3.x.next = y.next
4.tail.next = node(tem)
5.令tail=tail.next
最后得到w(w.value)->x(y.value)->z(z.value)->new(x.value)