力扣leetcode 面试题02.01 移除重复节点

面试题02.01 移除重复节点

编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。

示例1:

 输入:[1, 2, 3, 3, 2, 1]
 输出:[1, 2, 3]
示例2:

 输入:[1, 1, 1, 1, 2]
 输出:[1, 2]
提示:

链表长度在[0, 20000]范围内。
链表元素在[0, 20000]范围内。

解题思路:

1.哈希表,空间换时间

注意到题目给的是未排序的链表,因此,需要考虑的情况也就更为复杂。首先想到的是使用一个哈希表来记录已出现的val值,如果当前位置cur的val值已经在哈希表中存在,则该节点需要被删去。

需要格外考虑的是,在单链表中,若想删除当前节点,我们需要知道当前节点之前的链表节点。才能用pos->next=cur->next来执行删除操作。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeDuplicateNodes(ListNode* head) {
        //边界情况
        if(head==nullptr)
            return head;
        unordered_set<int> occurred={head->val};
        ListNode *pos=head;
        while(pos->next!=nullptr){
            ListNode* cur=pos->next;
            if(!occurred.count(cur->val)){
                occurred.insert(cur->val);
                pos=cur;
            }
            else{
                pos->next=cur->next;
            }
        }
        pos->next=nullptr;
        return head;
    }
};

时/空复杂度

时间复杂度:只需一次遍历,便可完成任务,因此为时间复杂度O(n)。

空间复杂度: 额外开辟了辅助空间来存储已出现过得元素值,因此空间复杂度为O(n)。

2.暴力法,时间换空间

        如果不使用额外空间,想要保持时间复杂度为O(n)是不现实的,因此,使用双重循环来解决问题,使用指针pos来记录一重循环当前链表位置值(pos需要保持不动,直到后续元素全部被遍历到),cur指针来记录二重循环中当前位置,用来对重复元素进行删除。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeDuplicateNodes(ListNode* head) {
        if(head==nullptr)
            return head;
        ListNode *pos=head;
        while(pos!=nullptr){
            ListNode *cur=pos;
            while(cur->next!=nullptr){
                if(cur->next->val==pos->val)
                    cur->next=cur->next->next;
                else
                    cur=cur->next;
            }
            pos=pos->next;
        }
        return head;
    }
};

时/空复杂度:

        时间复杂度:双重循环,时间复杂度为O(n^{2})

        空间复杂度:没有用到额外空间,空间复杂度为O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值