5月25日刷题笔记——数组
题目1:217. 存在重复元素(简单题)
我的题解:
思路:哈希表key为值,value为出现的次数。循环两次,value大于2说明重复返回true。循环结束返回false。(通过)
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_map<int, int> m;
for(auto i : nums){
m[i]++;
}
for(auto i : nums){
if(m[i] >= 2){
return true;
}
}
return false;
}
};
优秀题解:
方法1:评论区找的大佬题解,用set集合存放nums数组,如果集合长度不等于原数组长度说明有重复的。
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
return set<int>(nums.begin(), nums.end()).size() != nums.size();
}
};
方法2:官方题解,先排序,从小到大,循环遍历,如果相邻两元素相等,返回true,循环结束说明都不同,返回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;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/contains-duplicate/solution/cun-zai-zhong-fu-yuan-su-by-leetcode-sol-iedd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
方法3:哈希表,循环数组插入元素,如果发现元素已存在于哈希表中,返回true,循环结束返回false。
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> s;
for (int x: nums) {
// find()函数查找哈希表中key为x的键值对是否存在,如果没找到则返回s.end()
if (s.find(x) != s.end()) {
return true;
}
// 哈希表内不存在时,插入元素
s.insert(x);
}
return false;
}
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/contains-duplicate/solution/cun-zai-zhong-fu-yuan-su-by-leetcode-sol-iedd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复现优秀题解:
(代码简洁了很多,不过执行时间和内存消耗都比刚刚多一点)
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
set<int> s(nums.begin(), nums.end());
return s.size() != nums.size();
}
};
根据官方的哈希表题解更改了自己的题解,减少了一个循环:
(用时少)
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_map<int, int> m;
for(auto i : nums){
// 哈希表内找到key为i的键值对,说明之前已经存在该元素了,返回true
if(m.find(i) != m.end()){
return true;
}
// 否则插入该元素
m[i]++;
}
return false;
}
};
总结知识点:
1.set集合内存放的都是无序不重复的数组。可以使用 set s(nums.begin(), nums.end());的方式将数组nums插入到新建的集合s中。
2.哈希表中的find(x)函数为判断key为x的键值对是否存在,不存在返回end()
// eg
if(m.find(2)!=m.end()) //判断找到了key为2的键值对
3.思路最重要!!!
题目2:53. 最大子数组和(简单题)
没写出来,最后根据题解的动态规划复现代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
// 定义一个指针用来存放前一元素,初始化为0则意味着当前元素+前一元素必须大于0才会被记录
int pre = 0, maxSum = nums[0];
for(int i = 0; i < nums.size(); i++){
// 如果当前元素+前一元素大于前一元素,则加上该元素,继续往下
// 当前元素+前一元素小于前一元素时,则前一元素指针指向当前元素,从当前元素开始继续比较相加
// eg: -2,1,-3,4,-1,2,1,-5,4
// 当前元素为-2时,pre=max(0-2,-2)=-2,maxSum=max(-2,-2)=-2;
// 当前元素:1 pre=max(-2+1,1)=1 maxSum=max(-2,1)=1;
// 当前元素:-3 pre=max(1-3,-3)=-2 maxSum=max(1,-2)=1;
// 当前元素:4 pre=max(-2+4,4)=4 maxSum=max(1,4)=4;
// 当前元素:-1 pre=max(4-1,-1)=3 maxSum=max(4,3)=4;
// 当前元素:2 pre=max(3+2,2)=5 maxSum=max(4,5)=5;
// 当前元素:1 pre=max(5+1,1)=6 maxSum=max(5,6)=6;
// 当前元素:-5 pre=max(6-5,-5)=1 maxSum=max(6,1)=6;
// 当前元素:4 pre=max(1+4,4)=5 maxSum=max(6,5)=6;
pre = max(pre+nums[i], nums[i]);
maxSum = max(maxSum, pre);
}
return maxSum;
}
};