/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
反转链表的五种方法
反转链表
双指针法(迭代)
让前一个指针比后一个指针多走一步,然后让后一个的下一个保存下来,改变指针方向,然后让两个指针向后走便可。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode *pre = NULL;
struct ListNode *cur = head;
while (cur) {
struct ListNode *temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
递归法
在递的过程先将头节点一直往后给,直到下一个节点为空,此时将最后一个节点当作了新链表的头节点,然后开始归,先将此时的节点的下一个保存住,然后让下一个节点的下一个是这个节点,也就是此时的head,最后返回新的头节点便可。
注意\\,:在归的过程,需要在改变完节点方向时,需要将head的下一个方成空,否则成环,超出时间限制。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode *re_head = reverseList(head->next);
struct ListNode *temp = head->next;
temp->next = head;
head->next = NULL;
return re_head;
}
虚拟头节点
逻辑上,我将此法看作为迭代双指针,但是此处的虚拟头节点是本质存在的,而且是不变的,变的是dummy->next,此处可以省略头节点为NULL的情况
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode *dummy = (struct ListNode *)malloc(sizeof(struct ListNode));
dummy->next = NULL;
struct ListNode *cur = head;
while (cur) {
struct ListNode *nex = cur->next;
cur->next = dummy->next;
dummy->next = cur;
cur = nex;
}
return dummy->next;
}
数组—容器
这个可能是最笨重的方法,就是重新开辟个数组,先遍历存下链表的数组,然后再开一个链表来获取信息。这里要注意对开辟的链表进行初始化,否则会有不确定的值出现。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
int arr[5000];
int n = 0;
struct ListNode* cur = head;
while (cur) {
arr[n] = cur->val;
cur = cur->next;
n++;
}
struct ListNode* dummy = (struct ListNode* )malloc(sizeof(struct ListNode));
dummy->next = NULL;
struct ListNode* temp = dummy;
while (n—) {
struct ListNode* new = (struct ListNode* )malloc(sizeof(struct ListNode));
new->val = arr[n];
new->next = NULL;
temp->next = new;
temp = new;
}
return dummy->next;
}
尾递归
主要还是采用递归的思想,再设置一个函数,同时采用双指针,用递归替代赋值的思想。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* tool(struct ListNode* pre, struct ListNode* cur) {
if (cur == NULL) {
return pre;
}
struct ListNode* nex = cur->next;
cur->next = pre;
return tool(cur, nex);
}
struct ListNode* reverseList(struct ListNode* head) {
return tool(NULL, head);
}
网硕互联帮助中心




评论前必须登录!
注册