1、LeetCode203
解法一:在原链表(无头结点)的基础上进行删除链表元素,注意头结点的删除和非头结点的删除不同
struct ListNode* removeElements(struct ListNode* head, int val){
// 删除符合条件的头结点
while (head != NULL && head->val == val) {
struct ListNode *q = head;
head = head->next;
free(q);
}
// 头结点之后的结点
struct ListNode *p = head;
while (p != NULL && p->next != NULL) {
if (p->next->val == val) {
struct ListNode *q = p->next;
p->next = q->next; // p的next指针指向下一个结点
// 这里p指针的指向不能变,防止有两个目标数值连续出现[1, 2, 2, 1], val = 2
free(q);
} else {
p = p->next;
}
}
return head;
}
解法二:建立虚拟头结点
struct ListNode* removeElements(struct ListNode* head, int val){
// 虚拟头结点s
struct ListNode *s = (struct ListNode *) malloc(sizeof(struct ListNode));
struct ListNode *p = s;
s->next = head;
while (p != NULL && p->next != NULL) {
if (p->next->val == val) {
struct ListNode *q = p->next;
p->next = q->next;
free(q);
} else {
p = p->next;
}
}
head = s->next;
free(s);
return head;
}
2、LeetCode206
解法一:双指针法
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *cur = head; // 指向原链表的头结点
struct ListNode *pre = NULL; // 指向反转后的链表的头结点
struct ListNode *temp = cur; // 临时指针,在cur改变指向时,记录原链表的位置
while (cur) {
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
head = pre;
return head;
}
解法二:递归!!!!!
struct ListNode* reverse(struct ListNode* cur, struct ListNode* pre) {
if (cur == NULL) return pre;
struct ListNode* temp = cur->next;
cur->next = pre;
return reverse(temp, cur);
}
struct ListNode* reverseList(struct ListNode* head){
return reverse(head, NULL);
}