leetcode每日一题23

文章介绍了使用不同方法解决两个编程问题:反转链表和查找数组中重复的元素。对于反转链表,提供了迭代的解决方案;在查找重复元素时,对比了哈希表、排序和集合的不同策略,以及它们的时间和空间复杂度。此外,还探讨了在限制元素间距的情况下查找重复元素的滑动窗口方法。
摘要由CSDN通过智能技术生成

206. 反转链表

按照题意挨个反转就行

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==nullptr)
            return head;
        ListNode *first,*cur,*last;
        first=nullptr;
        cur=head;
        last=head->next;
        while(last)
        {
            cur->next=first;
            first=cur;
            cur=last;
            last=last->next;
        }
        cur->next=first;
        return cur;
    }
};

217. 存在重复元素

第一反应还是哈希表

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_map<int,int> hash;
        for(int i=0;i<nums.size();i++)
        {
            hash[nums[i]]++;
            if(hash[nums[i]]>1)
                return true;
        }
        return  false;
    }
};

无论是时间还是空间复杂度都很高
发现官方题解里的哈希表用的是set,然后每次插入数的时候在set里find一下该数字,如果找到了,返回true

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_set<int> s;
        for (int x: nums) {
            if (s.find(x) != s.end()) {
                return true;
            }
            s.insert(x);
        }
        return false;
    }
};

第二种解法是排序,然后找到前后一致的数字

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for (int i = 0; i < n - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                return true;
            }
        }
        return false;
    }
};

竟然比哈希表还快点,这有天理吗😭
评论区还有一个很简洁的

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_set<int> s(nums.begin(), nums.end());
        return s.size() != nums.size();
    }
};

因为set里没有重复的元素,因此把整个vector放进去后,看vector和set的大小一不一样就可以了

219. 存在重复元素 II

这道题反正不能用排序做了
但是我也没思路
看了一下大佬的思路
维护⼀个只有 K 个元素的 map,每次只需要判断这个 map 里面是否存在这个元素即可。如果存在就代表重复数字的下标差值在 K 以内。map 的长度如果超过了 K 以后就删除掉 i-k 的那个元素,这样⼀直维护 map 里面只有 K 个元素。

想到上一题那个set,可以当set长度大于k+1时,删除最先存入的那个数字来维持窗口长度

class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        unordered_set<int> window;
        int last=0;
        for(int i=0;i<nums.size();i++)
        {
            if(window.size()==k+1)
                window.erase(last);
            if (window.find(nums[i]) != window.end()) {
                return true;
            }
            window.insert(nums[i]);
            if(i>=k)
                last=nums[i-k];
        }
        return false;
    }
};

时间复杂度比较高,空间复杂度很低
官方题解里的哈希表解法就快一些了

class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        unordered_map<int, int> dictionary;
        int length = nums.size();
        for (int i = 0; i < length; i++) {
            int num = nums[i];
            if (dictionary.count(num) && i - dictionary[num] <= k) {
                return true;
            }
            dictionary[num] = i;
        }
        return false;
    }
};

题解里是直接把数组下标用于计算中的计数了。确实比我想的更好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值