LeetCode之路:217. Contains Duplicate

一、引言

来,跟我读:

duplicate
[ˈdu:plɪkeɪt]
n.副本;完全一样的东西 ;复制品

做完这道题,一定要记住这个单词的含义。

就这道题而言,其实还是非常简单的,先让我们看看这道题:

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice int the array, and it should return false if every element is distinct.

题目信息非常少,简单翻译下:

给定元素为整型数字的数组,请判断里面是否含有重复的元素。当出现了重复的元素,应该返回真值,否则,返回假值

这道题其实非常简单,让我们试着挑战下自己,如何写出更加简洁的代码。

二、第一个方法:std::map

相对来说,我非常钟爱 map,可能是实际开发中 map 实在帮我解决了太多的复杂问题了吧。

根据题意,我们要寻找重复元素,那么 map 中,键值存储元素,值存储出现次数即可:

// my solution 1 , runtime = 59 ms
class Solution1 {
public:
    bool containsDuplicate(vector<int>& nums) {
        map<int, int> num_count;
        for (auto i : nums) if (++num_count[i] > 1) return true;
        return false;
    }
};

代码逻辑非常清晰,不再赘述。

三、第二个方法:std::set

仿佛 std::set 总是伴随着 std::map 出现。

使用 set 的逻辑与第一个方法有所不同,遍历过程中,不断检查该元素是否已经出现(是否存在于 std::set 中),根据检查结果返回结果:

// my solution 2 , runtime = 49 ms
class Solution2 {
public:
    bool containsDuplicate(vector<int>& nums) {
        set<int> num_set;
        for (auto i : nums)
            if (num_set.find(i) != num_set.end()) return true;
            else num_set.insert(i);
        return false;
    }
};

这里使用 std::set 反而使得代码量增加,不过就空间使用率上来说绝对占优。

四、第三个方法:std::sort & std::unique

到了这里,还没有其他的方法呢?

当然是有的:

std::unique
定义于头文件 <algorithm>
删除所有连续重复的元素,然后重新排列输入范围内的元素,并且返回一个迭代器

想要详细了解 std::unique 的同学可以点击这里 C++在线参考手册之 std::unique

这里需要注意的是,连续 这两个字,std::unique 只能移走(到后面)相邻的重复元素,所以这里需要与排序配合:

// my solution 3, runtime = 32 ms
class Solution3 {
public:
    bool containsDuplicate(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return unique(nums.begin(), nums.end()) != nums.end();
    }
};

这里,通过 std::unique 返回的最后一个不重复元素的迭代器与数组的尾迭代器进行比较,得到结果。

五、惊为天人的方法:std::set 的构造函数

这个方法是我在讨论区中众多的答案中找出来的,觉得非常巧妙:

// perfect solution only one line , runtime 36 ms
class Solution4 {
public:
    bool containsDuplicate(vector<int>& nums) {
        return set<int>(nums.begin(), nums.end()).size() < nums.size();
    }
};

这个方法只有一行代码:

  1. 首先,使用 std::set 的构造函数构造了一个指定输入范围的集合

  2. 然后,计算 std::set 的长度(没有重复的元素长度应该与输入范围一致)

  3. 最后,根据比较结果返回值

如果选择一个最佳答案,这个方法将是我心目中最优雅的方法 ^_^

六、总结

尽管这道题很简单,却还是促使我使用了三个方法来解决问题;另外,最后的“最佳答案”也确实够优雅。不得不说,这道小题已经足够让人觉得惊讶了。

很久没有刷 LeetCode 了(大概能有个 5 天),这段时间公司业务比较繁忙,处理业务逻辑实在是分不开心。

其实公司的业务逻辑也很锻炼人的抽象能力,数据结构学得好的话,能够更加便利些。我也还在加油吧。

写代码是一种快乐,继续,还要继续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值