删除链表中等于给定值 val 的所有结点。

  1. 输入:1->2->6->3->4->5->6
  2. 输出:1->2->3->4->5

此题的关键问题要考虑链表头部结点判断问题,这里我采用的是从第二个元素开始依次判断,然后最终再比较头结点。

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * struct ListNode *next;
  6. * };
  7. */
  8. struct ListNode* removeElements(struct ListNode* head, int val){
  9. // 特殊情况判断 容错处理
  10. if (head == NULL) return head;
  11. if (head->next == NULL) {
  12. if (head->val == val) {
  13. return NULL;
  14. } else {
  15. return head;
  16. }
  17. }
  18. struct ListNode *target = head;
  19. // 从第二个结点依次判断
  20. while (target->next) {
  21. if (target->next->val == val) {
  22. target->next = target->next->next;
  23. } else {
  24. target = target->next;
  25. }
  26. }
  27. // 判断头结点
  28. if (head->val == val) head = head->next;
  29. return head;
  30. }

但是还有别的思路

添加虚拟头节点

由于我们对于头节点需要单独判断,我们也可以给当前链表添加一个虚拟头结点,然后就可以不用考虑头结点的问题了

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * struct ListNode *next;
  6. * };
  7. */
  8. struct ListNode* removeElements(struct ListNode* head, int val){
  9. if (head == NULL) return head;
  10. struct ListNode *addNode = (struct ListNode*) malloc(sizeof(struct ListNode));
  11. addNode->val = val-1;
  12. addNode = head;
  13. head = addNode;
  14. struct ListNode *target = head;
  15. while (target->next) {
  16. if (target->next->val == val) {
  17. target->next = target->next->next;
  18. } else {
  19. target = target->next;
  20. }
  21. }
  22. if (head->val == val) head = head->next;
  23. return head;
  24. }

递归

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * struct ListNode *next;
  6. * };
  7. */
  8. struct ListNode* removeElements(struct ListNode* head, int val){
  9. if (head == NULL) return NULL;
  10. head->next = removeElements(head->next,val);
  11. if (head->val == val) {
  12. return head->next;
  13. } else {
  14. return head;
  15. }
  16. }