竞赛链接:https://leetcode-cn.com/contest/weekly-contest-141
1.复写零:
从前往后遍历数组,遇到0就把一个新的0插入到该0的后面,然后后面的元素依次右移。需要注意的是,为保证不一直插入0,插入新的0后要将i加两次1(for循环中有一次然后再自加一次)。
上AC代码:
void duplicateZeros(int* arr, int arrSize){
int i,j;
for(i=0;i<arrSize;i++)
{
if(arr[i]==0)
{
for(j=arrSize-1;j>i+1;j--)
{
if(j-1>=0)
arr[j]=arr[j-1];
}
if(i+1<arrSize)
arr[i+1]=0;
i++;
}
}
}
2.受标签影响的最大值:
这道题虽然看着很麻烦,其实是纸老虎。贪心策略。自定义一个结构体将values和labels绑在一起,按values从大到小排序,遍历结构体数组即可。判断是否满足子集中标签的值的种类数小于use_limit可以使用标记法,开一个20001大小的数组dp即可快速得到0~20000这些值出现的次数,元素个数加到num_wanted为止。
上AC代码:
class Solution {
public:
struct zuhe
{
int val;
int lab;
};
int dp[20001];
zuhe st[20001];
static bool cmp(zuhe a,zuhe b)
{
return a.val>b.val;
}
int largestValsFromLabels(vector<int>& values, vector<int>& labels, int num_wanted, int use_limit) {
int ret=0;
int i;
int valuesSize=values.size();
for(i=0;i<valuesSize;i++)
{
st[i].val=values[i];
st[i].lab=labels[i];
}
memset(dp,0,sizeof(dp));
sort(st,st+valuesSize,cmp);
int num=0;
for(i=0;i<valuesSize;i++)
{
if(num<num_wanted&&dp[st[i].lab]<use_limit)
{
ret+=st[i].val;
dp[st[i].lab]++;
num++;
}
}
return ret;
}
};
3.二进制矩阵中的最短路径
同样是纸老虎,不要被二进制和矩阵吓到,本质是个在二维空间上8个方向的广度优先搜索(bfs),遇到1阻塞,遇到0畅通。广度优先搜索队列完成,用二维数组dp标记已经走过的步数,最后返回dp[size-1][size-1]。
上AC代码:
class Solution {
public:
struct pos
{
int x,y;
};
int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
int ret=-1;
if(grid[0][0]==1)
return -1;
int size=grid.size();
queue<pos> que;
int dp[size][size];
pos start;
start.x=0;
start.y=0;
memset(dp,-1,sizeof(dp));
dp[0][0]=1;
que.push(start);
while(!que.empty())
{
pos temp=que.front();
que.pop();
int dx,dy;
int nowx=temp.x;
int nowy=temp.y;
if(nowx==size-1&&nowy==size-1)
{
ret=dp[nowx][nowy];
break;
}
for(dx=-1;dx<=1;dx++)
{
for(dy=-1;dy<=1;dy++)
{
if(nowx+dx>=0&&nowx+dx<size&&nowy+dy>=0&&nowy+dy<size&&grid[nowx+dx][nowy+dy]==0&&dp[nowx+dx][nowy+dy]==-1)
{
dp[nowx+dx][nowy+dy]=dp[nowx][nowy]+1;
pos t;
t.x=nowx+dx;
t.y=nowy+dy;
que.push(t);
}
}
}
}
return ret;
}
};