当前位置 博文首页 > yumoz:LeetCode203-移除链表元素(哨兵位头节点法重点解释)

    yumoz:LeetCode203-移除链表元素(哨兵位头节点法重点解释)

    作者:[db:作者] 时间:2021-07-14 15:41

    题目描述

    给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。移除链表元素题目链接。

    说明

    在这里插入图片描述

    题目分析

    题目已知head头节点,val = 6。
    在这里插入图片描述

    解法:哨兵位头节点

    预设工作,确定各节点

    struct ListNode* guardHead = (struct ListNode*)malloc(sizeof(struct ListNode));
        guardHead->next = head;
        struct ListNode* cur = head;
        struct ListNode* prev = guardHead;
    

    第一步:
    在这里插入图片描述
    第二步:cur->val != val 继续迭代。
    在这里插入图片描述
    第三步:cur->val == val
    在这里插入图片描述
    代码:

    if(cur->val == val)
    {
    	struct ListNode* next = cur->next;
    	prev->next = next;
        free(cur);
        cur = next;                
    }
    else 
    {
        prev = cur;
        cur = cur->next;
    }        
    

    第四步:val 在结尾特殊判断
    在这里插入图片描述
    第五步:返回语句特殊判断
    在这里插入图片描述

    head = guardHead->next;
    free(guardHead);
    return head;
    

    整体代码

    struct ListNode* removeElements(struct ListNode* head, int val){
        struct ListNode* guardHead = (struct ListNode*)malloc(sizeof(struct ListNode));
        guardHead->next = head;
        struct ListNode* cur = head;
        struct ListNode* prev = guardHead;
    
        while(cur)
        {       if(cur->val == val)
                {
                    struct ListNode* next = cur->next;
                    prev->next = next;
                    free(cur);
                    cur = next;
                }
                else 
                {
                    prev = cur;
                    cur = cur->next;
                }    
        }
        head = guardHead->next;
        free(guardHead);
        return head;
    }
    

    其他解法(前驱指针法)

    参考链接移除链表元素代码链接。
    代码:

    struct ListNode* removeElements(struct ListNode* head, int val){
        struct ListNode* cur = head;
        struct ListNode* prev = NULL;
    
        while(cur)//cur控制循环体结束
        {
            if(cur->val == val)// find it
            {
                struct ListNode* next = cur->next;
    			
    			//头节点是val 需要单独判断
                if(prev == NULL)//cur 前的prev为空 cur是头
                {
                    free(cur);
                    head = next;
                    cur = next;
                }
                else //cur不是头 要删除的不是头结点
                {
                    prev->next = next;
                    free(cur);
                    cur = next;
                }
            }
            
    		//没找到val ,继续迭代找val相等的节点
            else
            {
                prev = cur;
                cur = cur->next;
            }
        }
        return head;
    }
    

    这里选取待哨兵位头节点的原因是防止了上述代码方法对头节点的单独判断。

    cs