1.leetcode 727 最小窗口子序列(dp记录的是起始位置,长度通过计算得到)
给定字符串S和T,在S中寻找最小连续子串W,使得T是W的子序列(有序)。如果没有找到返回"",如果找到多个最小长度的子串,返回左 index 最小的。
https://blog.csdn.net/weixin_45588823/article/details/100642933
与727的差别是“给定字符串S和T,在S中寻找最小连续子串W,使得W包含所有T中字符,即可以乱序。”
思路是头尾指针,尾一直往后走直到完全包含T,然后开始走头(此时一边走一边记录最短子串)直到走到不完全包含T了,再继续走尾,循环往复(走尾一个while,包含 走头一个while)
https://blog.csdn.net/whdAlive/article/details/81132383
3.leetcode 1139 最大的以 1 为边界的正方形
思路我想到了,跟之前的正方形差不多,以[i][j]为右下角的记录两个dp(一个往右最长走多少,一个往上最长走多少),然后从这两个里面选一个小的,从大到小枚举这个正方形的边长,判断是否可行,记录ans。(本来想记录四条边的,但是发现只有两条边是跟右下角有关的,边还是不确定得枚举,所以记录两条边是最好的)
class Solution {
public:
int largest1BorderedSquare(vector<vector<int>>& grid) {
if (grid.size()==0 || grid[0].size()==0) return 0;
int n=grid.size(),m=grid[0].size();
int ans=0;
//f[i][j][0]表示往左最长,f[i][j][1]表示往上最长
int f[n+10][m+10][2];
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (grid[i-1][j-1]==1)
{
f[i][j][0]=f[i][j-1][0]+1;
f[i][j][1]=f[i-1][j][1]+1;
int maxlen=f[i][j][0];
if (f[i][j][1]<maxlen) maxlen=f[i][j][1];
for (int k=maxlen;k>ans;k--)
{
if (f[i][j-k+1][1]>=k && f[i-k+1][j][0]>=k)
{
ans=k;
break;
}
}
}
return ans*ans;
}
};
4.