栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

力扣刷题记录六:203、移除链表元素

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

力扣刷题记录六:203、移除链表元素

记录力扣刷题第六题:

本文包含C++三种解法和Python与Java的主观认为的最优解法

题目描述如下

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

来源:LeetCode

思路: 其实就是个单链表的删除操作,对数据结构有一些了解的都知道该怎么做吧。关键的一点是要注意对头节点的删除操作,如果用传统方法,只需要把head向后移即可,可是这样就需要单独写对头节点的删除函数。代码如下:
 

以上为题中对单链表的描述,其中对链表节点也写构造函数是我们需要参考的。

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
    	//首先写对头节点的操作
    	//注意也要判断head不为空,否则当head为空时运行会出错
    	while(head != nullptr && head->val == val) {
    	//注意这里要用while不是if,以防出现连续值等于val的节点都为头节点
    		ListNode* temp = head;
    		head = head->next;
    		//对删除的节点进行释放
    		delete temp;
    	}
    	cur = head;
    	//再写对非头节点的操作,注意while里要先判断cur不为空
    	//如果cur为空的话也就没有next,执行就会出错
    	while(cur != nullptr && cur->next != nullptr) {
    		if(cur->next->val == val) {
    			ListNode* temp = cur->next;
    			cur->next = temp->next;
    			//对删除的节点进行释放
    			delete temp;
    		}
    		else {
    			cur = cur->next;
    		}
    	}
    	return head;
    }
};

时间消耗主要用于查找到待删除节点的前一个节点,因此时间复杂度为O(n),没有额外的空间消耗,空间复杂度为O(1)。

但是对头节点和非头节点分开操作真的好麻烦呀,有没有能够将两者统一的方式呢?显然是有的,只需要在头节点前面再加一个头节点
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
    //创建一个虚拟头节点
        ListNode* VHead = new ListNode(-1);
        VHead->next = head;
        ListNode* cur = VHead;
        //cur必定不为空
        while(cur->next != nullptr) {
            if(cur->next->val == val) {
                ListNode* temp = cur->next;
                cur->next = temp->next;
                //对删除的节点进行释放
                delete temp;
            }else {
                cur = cur->next;
            }
        }
        head = VHead->next;
        //注意对自己创建的节点也要进行释放
        delete VHead;
        return head;
    }
};

时间复杂度为O(n),空间复杂度为O(1)。

这样是不是简洁美观多啦,运行时间也减少了,其实下面还有更简洁的方法,但我主观认为这是最好的解法。 下面介绍一个更简洁的方法:递归写法
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
    	if(head == nullptr) {
    		return head;
    	}
    	//递归调用removeElements
    	head->next = removeElements(head->next, val);
    	if(head->val == val) {
    		ListNode* temp = head;
    		head = head->next;
    		delete temp;
    	}
    	return head;
    }
};

时间复杂度:O(n)。
空间复杂度:由于递归调用栈,栈的层数最多不超过n层,因此为O(n)。

但链表很长时会有爆栈的风险,而且这种方法空间复杂度比较大,因此不推荐用。 所以我主观认为最好的解法还是添加头节点法。
下面放上Java和Python的添加头节点法 Java
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode VHead = new ListNode(-1);
        VHead.next = head;
        ListNode cur = VHead;
        while(cur.next != null) {
            if(cur.next.val == val) {
                cur.next = cur.next.next;
            }
            else {
                cur = cur.next;
            }
        }
        head = VHead.next;
        return head;
    }
}

Python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        VHead = ListNode()
        VHead.next = head
        cur = VHead
        while cur.next != None:
            if cur.next.val == val:
                cur.next = cur.next.next
            else:
                cur = cur.next
        head = VHead.next
        return head
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/920777.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号