一、重复N次的元素LeetCode961题
1.1 题目描述
在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N 次。
返回重复了 N 次的那个元素。
示例 1:
输入:[1,2,3,3]
输出:3
示例 2:
输入:[2,1,2,5,3,2]
输出:2
示例 3:
输入:[5,1,5,2,5,3,5,4]
输出:5
提示:
4 <= A.length <= 10000
0 <= A[i] < 10000
A.length 为偶数
1.2 解题思路
解法一:
- 计数法,思路很简单,这里我们用到unordered_map,因为我们不需要对数据进行排序,因此用unordered_map效率更高,通过将每个数字出现的次数进行统计,unordered_map使用原来可以参考博客:unordered_map/set的使用, 统计次数之后,再遍历countmap查看是否有数字出现的次数大于等于N次,有则返回该数即可
解法二:
- 也可使用unordered_set进行求解,算是基于解法一的一个优化,优化的依据在于:依据题意,有一个数字出现了N次,而其余数字都只出现了一次。所以重复出现的数字便是出现了N次的数字,我们只需遍历vector取得vector的数在unordered_set中进行插入,插入失败的数即为重复出现N次以上的数,这个方法有点取巧,不太建议使用,但是效率提高了很多。
1.3 代码实现
解法一:
class Solution {
public:
int repeatedNTimes(vector<int>& A) {
unordered_map<int,int> countmap;
for(auto& e : A)
{
countmap[e]++;
}
for(auto& kv : countmap)
{
if(kv.second >= A.size()/2)
return kv.first;
}
return 0;
}
};
解法二:
class Solution {
public:
int repeatedNTimes(vector<int>& A) {
unordered_set<int> us;
for (auto e: A) {
auto ret = us.insert(e);
if (ret.second == false)
return e;
}
return -1;
}
};
二、两句话中不常见的单词
2.1 题目描述
给定两个句子 A 和 B 。 (句子是一串由空格分隔的单词。每个单词仅由小写字母组成。)
如果一个单词在其中一个句子中只出现一次,在另一个句子中却没有出现,那么这个单词就是不常见的。返回所有不常用单词的列表。您可以按任何顺序返回列表。
示例 1:
输入:A = “this apple is sweet”, B = “this apple is sour”
输出:[“sweet”,“sour”]
示例 2:
输入:A = “apple apple”, B = “banana”
输出:[“banana”]
提示:
0 <= A.length <= 200
0 <= B.length <= 200
A 和 B 都只包含空格和小写字母。
2.2 解题思路
- 通过find找到每个单词之间的空格以分隔每个单词,再使用substr取得每个单词,以此类推取得所有的单词并在countmap中统计每个单词出现的次数
- 最后遍历一遍countmap找到只出现一次的单词放入之前创建的vector中,返回即可
2.3 代码实现
class Solution {
public:
vector<string> uncommonFromSentences(string A, string B) {
A += ' ';
A += B; //将A B字符串进行连接
unordered_map<string,int> countmap;
vector<string> v;
size_t start = 0;
size_t pos = 0;
do
{
pos = A.find(' ',start);
countmap[A.substr(start,pos-start)]++;//去每个单词,并统计次数
start = pos + 1;
}while(pos < A.size());
for(auto& kv : countmap)
{
if(kv.second == 1)
v.push_back(kv.first);
}
return v;
}
};
三、存在重复元素LeetCode217题
3.1题目描述
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
3.2 解题思路
解法一:
- 用到unordered_map,同样是统计每个数出现的次数,之后再遍历一遍unordered_map若有元素出现超过一次说明存在重复元素,返回true,若没有就返回false
解法二:
- 思路很简单,用到了unordered_set,其实和重复n次的元素的思路一样,遍历取得vector中的元素插入到unordered_set中,如果插入失败说明有重复的元素 ,返回true,若没有则返回false即可
解法三:
- 这是这三种方法中效率最高的一个,思路也很简单,将vector数组中的元素进行排序,再两两比较,若有相同的两个元素,说明存在重复元素,返回true,否则返回false。
3.3 代码实现
解法一:
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_map<int,int> countmap;
for(auto& e : nums)
{
countmap[e]++;
}
for(auto& kv : countmap)
{
if(kv.second > 1)
return true;
}
return false;
}
};
解法二:
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> us;
for(auto& e:nums)
{
auto ret = us.insert(e);
if(ret.second == false)
return true;
}
return false;
}
};
解法三:
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
if(nums.empty())
return false;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-1;i++)
{
if(nums[i]==nums[i+1])
return true;
}
return false;
}
};
四、两个数组的交集LeetCode349题
4.1 题目描述
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]
示例 2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [9,4]
说明:
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。
4.2 解题思路
- 首先通过unordered_set对两个数组进行去重,再遍历第一个数组,找第一个数组中的元素也在第二个数组中出现了的元素,放进创建的vector数组中,返回该vector就是两个数组的交集。
4.3 代码实现
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
//用unordered_set对nums1的元素去重
unordered_set<int> s1;
for(auto& e : nums1)
{
s1.insert(e);
}
//用unordered_set对nums2的元素去重
unordered_set<int> s2;
for(auto& e : nums2)
{
s2.insert(e);
}
vector<int> v;
//遍历s1,如果s1中的某个元素在s2中出现,即为二者交集
for(auto& e : s1)
{
if(s2.find(e) != s2.end())
v.push_back(e);
}
return v;
}
};