LeetCode日记2020.2.20
文章目录
双指针这种东西真是让人又爱又恨,DP也总是差些火候。
287 寻找重复数(mid)
转化为链表定位入环点的问题
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int slow = 0;
int fast = 0;
slow = nums[slow];
fast = nums[nums[fast]];
while(slow!=fast)
{
slow = nums[slow];
fast = nums[nums[fast]];
}
int dup = 0;
while(dup!=slow)
{
dup = nums[dup];
slow = nums[slow];
}
return dup;
}
};
也可以二分,统计左右区间的元素数目哪边多重复元素就在哪边然后继续二分。
41 缺失的第一个正数(hard)
桶排序(一个萝卜一个坑)
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int i=0, n=nums.size();
while(i<nums.size())
{
if(nums[i]>0 && nums[i]<n+1 && nums[i]!=i+1 && nums[nums[i]-1] != nums[i])
swap(nums[i], nums[nums[i]-1]);
else
++i;
}
for(int j=0;j<n;++j)
{
if(nums[j] != j+1)
return j+1;
}
return n+1;
}
};
714 买卖股票的最佳时机(mid)
这种题关键在于DP问题的转化。
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
if(prices.size()<2)
return 0;
int cash = 0;
int hold = -prices[0];
for(int i=1;i<prices.size();++i)
{
cash = max(cash, hold+prices[i]-fee);
hold = max(hold, cash-prices[i]);
}
return cash;
}
};
11 盛水最多的容器(mid)
双指针!!!!
class Solution {
public:
int maxArea(vector<int>& height) {
int beg = 0, End = height.size()-1;
int maxA = numeric_limits<int>::min();
while(beg < End)
{
int area = (End - beg) * min(height[beg], height[End]);
if(area > maxA)
maxA = area;
height[beg] < height[End] ? ++beg: --End;
}
return maxA;
}
};
1338 数组大小减半(mid)
class Solution {
public:
int minSetSize(vector<int>& arr) {
map<int, int> se;
vector<int> ps;
for(auto i: arr)
{
if(se.find(i) == se.end())
{
se.insert(make_pair(i, ps.size()));
ps.push_back(1);
}
else
++ps[se[i]];
}
sort(ps.rbegin(), ps.rend());
int sum = 0, half = arr.size()/2;
for(int i=0;i<ps.size();++i)
{
sum += ps[i];
if(sum >= half)
return i+1;
}
return 0;
}
};
695 岛屿最大面积(mid)
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int m = grid.size(), n = grid.front().size();
vector<vector<int>> adj(m*n);
vector<int> flags(m*n, 0);
int drs[4] = {-1, 0, 1, 0};
int dcs[4] = {0, 1, 0, -1};
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if(grid[i][j] == 1)
{
flags[i*n+j] = 1;
for(int k = 0;k<4;++k)
{
int row = drs[k] + i;
int col = dcs[k] + j;
if(row >=0 && row < m && col >= 0 && col < n && grid[row][col] == 1)
adj[i*n + j].push_back(row*n + col);
}
}
}
}
int maxC = 0;
for(int i=0;i<flags.size();++i)
{
if(flags[i] == 1)
{
int sum = dfs(flags, adj, i);
if(sum > maxC)
maxC = sum;
}
}
return maxC;
}
int dfs(vector<int>& flags, const vector<vector<int>>& adj, int root)
{
int cnt = 1;
flags[root] = 0;
for(auto i: adj[root])
{
if(flags[i] == 1)
cnt += dfs(flags, adj, i);
}
return cnt;
}
};
本文深入探讨了LeetCode上的多个经典算法题目,包括寻找重复数、缺失的第一个正数、买卖股票的最佳时机等,通过详细代码解析,展示了双指针、DP、桶排序等技巧的应用。

4481

被折叠的 条评论
为什么被折叠?



