刷代码随想录的总结笔记,供回想思路所用...更具体可以去源站自己刷一刷。
链表的定义
链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null。
链表的入口节点称为链表的头结点也就是head。我们也经常设置一个虚头,方便对链表内部进行排序之类的操作。
// 单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};
链表的类型
单链表
上述介绍的“一条路走到黑”的就是单链表
双链表
有“头”也有“尾”的就是双链表,即既存放了下一个数据的地址,也存放了上一个数据的地址。
循环链表
最前面和最后面接在一起的就是循环链表(用来解决约瑟夫环比较合适)
链表的操作(也就是涉及到的考题)
链表的删除
链表的删除因为是一个接着一个的,所以只要把要删除的节点的前面和后面接起来,再把这个节点的空间释放掉就可以。
链表的添加
链表的添加,就是将需要添加的位置的前一个节点指向该节点,再指向原先的下一个节点,就能继续链起来了。
可以看出链表的增添和删除都是O(1)操作,也不会影响到其他节点。
但是要注意,要是删除第五个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)。
也就是说运气好是O(1),运气不好就是O(n)...
和数组相比,链表的增删效率高些,查询效率稍微低了点。、
循环链表找入口
重点记录这个题型,用快慢指针的方法,可以很容易找到循环点(入口)
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
// 快慢指针相遇,此时从head 和 相遇点,同时查找直至相遇
if (slow == fast) {
ListNode* index1 = fast;
ListNode* index2 = head;
while (index1 != index2) {
index1 = index1->next;
index2 = index2->next;
}
return index2; // 返回环的入口
}
}
return NULL;
1723






