《LeetCode之每日一题》:49.连续数组
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:49.连续数组相关的知识,希望对你有一定的参考价值。
题目链接: 连续数组
有关题目
给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
例 1:
输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量0和1的最长连续子数组。
示例 2:
输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。
提示:
1 <= nums.length <= 10^5
nums[i] 不是 0 就是 1
题解
前缀和+哈希表
思路:
优化一:如果答案非 0,那么子数组长度必然为偶数,且长度至少为 2
理解1.
转换,1的数量和0的数量相等,即1的数量减去0的数量为零
我们将数组的中的0视作-1,那么我们求解的题目就变为了
求最长的连续子数组,其元素和为0
理解2.
前缀的思想在于,利用不同段的计数作差来得出中间连续子数组的存在
因为我们需要知道的是存在性,所以我们只需要用哈希维护计数的存在即可
参考官方题解
代码一:
class Solution {
public:
int findMaxLength(vector<int>& nums) {
unordered_map<int,int> mp;
int counter = 0;
int maxLength = 0;//最大长度
mp[counter] = -1;//规定空串的前缀结束的下标为-1,空的前缀为元素和为0;
for (int i = 0; i < nums.size(); i++)
{
//为0counter--,为1counter++
if (nums[i] == 1)
counter++;
else
counter--;
if (mp.find(counter) != mp.end())
maxLength = max(maxLength,i - mp[counter]);
else
mp[counter] = i;
}
return maxLength;
}
};
代码二:
class Solution {
public:
int findMaxLength(vector<int>& nums) {
unordered_map<int,int> mp;
int sum = 0, ans = 0;
mp[sum] = -1;
for (int i = 0; i < nums.size(); i++)
{
sum += nums[i] ? 1 : -1;//这边?:的优先级顺序高于+=所以运算顺序为sum += (num[i] ? 1 :-1)
auto p = mp.find(sum);//find函数返回的是个地址
if (p != mp.end())
ans = max(ans, i - p->second);//根据hash表中的成员列表我们知道,second就是对应前缀和的下标
else
mp[sum] = i;
}
return ans;
}
};
代码三:(目前跑不过去)
参考宫水三叶
思路;
如何求得最长一段区间和为 0 的子数组。
同时使用「哈希表」来记录「某个前缀和出现的最小下标」是多少。
再结合「如果答案非 0,子数组长度至少为 2的特性,我们让循环从 2开始。
答案为零返回0
class Solution {
public:
int findMaxLength(vector<int>& nums) {
int ans = 0;
vector<int> sum(nums.size() + 1,0);
for (int i = 1; i <= nums.size(); i++)
sum[i] = sum[i - 1] + (nums[i - 1] == 1 ? 1 : -1);
unordered_map<int,int> mp;
mp[0] = -1;
for (int i = 2; i <= nums.size(); i++)
{
//同时使用「哈希表」来记录「某个前缀和出现的最小下标」是多少。
//再结合「如果答案非 0,子数组长度至少为 2的特性,我们让循环从 2开始。
if (mp.find(sum[i]) != mp.end())
ans = max(ans,i - mp[sum[i]]);
if (!mp.count(sum[i - 2]))
mp[sum[i - 2]] = i - 2;
}
return ans;
}
};
C版本
struct HashTable
{
int key,value;
UT_hash_handle hh;
};
int findMaxLength(int* nums, int numsSize){
int maxLength = 0;
struct HashTable* hashTable = NULL;
struct HashTable* tmp = (struct HashTable*)malloc(sizeof(struct HashTable));
tmp->key = 0, tmp ->value = -1;
HASH_ADD_INT(hashTable,key,tmp);
int counter = 0;
for (int i = 0;i < numsSize; i++)
{
if (nums[i] == 1)
counter++;
else
counter--;
HASH_FIND_INT(hashTable,&counter,tmp);
if (tmp != NULL)
maxLength = fmax(maxLength,i - tmp->value);
else
{
tmp = malloc(sizeof(struct HashTable));//重新开辟空间给tmp
tmp->key = counter,tmp->value = i;
HASH_ADD_INT(hashTable,key,tmp);
}
}
return maxLength;
}
以上是关于《LeetCode之每日一题》:49.连续数组的主要内容,如果未能解决你的问题,请参考以下文章
《LeetCode之每日一题》:77.绝对差不超过限制的最长连续子数组
《LeetCode之每日一题》:239.最大连续 1 的个数