具体思想:
卡在了dp条件上,其实思路不难想;
里面有一个坑,有两种情况:
- 该点当前有障碍,所以应该设置为不可达;
- 当前点无障碍,但是必须要要从上一个无障碍的地方跳过来;
所以判断特别繁琐,简单的判定方式为:
- 先判断当前是否有障碍,无障碍就直接从上一个地方跳过来;
- 在判断是否可以从同级的其他地方跳过来;
这样判断有一好处,第一个条件可以保证跳过来的点,在同一级中同水平必须可达,破除坑1,并且可以同时满足2,判断三个最小值;
例如:
1 o
o
1
第一列第二个位置不可达,要求补充第二列;
-
先判断当前是否有障碍,无障碍就直接从上一个地方跳过来;
可以得到:
1 o
o o
1 1
第二列中,第一个位置不可达,第二个位置从上一个位置不可达,第三个可以从上一个位置可达; -
在判断是否可以从同级的其他地方跳过来;
可以得到:
1 o
o 2
1 1
第二个位置可以由3可达,因为第一行并不可达;
所以相当于取了与操作;
具体代码:
class Solution {
public:
int minSideJumps(vector<int>& obstacles) {
int n=obstacles.size();
vector<vector<int>>dp(n,vector<int>(3,INT_MAX/2));
dp[0][0]=dp[0][2]=1;
dp[0][1]=0;
if(n==1)
return 0;
for(int i=1;i<n;i++){
int ob=obstacles[i]-1;
for(int j=0;j<3;j++){
if(j!=ob){
dp[i][j]=dp[i-1][j];
}
}
for(int j=0;j<3;j++){
if(ob==j){
//如果该处是障碍物;
//dp[i][j]=INT_MAX/2;
continue;
}
dp[i][j]=min(dp[i][j],min(dp[i][(j+1)%3],dp[i][(j+2)%3])+1);
}
}
return min(dp[n-1][0],min(dp[n-1][1],dp[n-1][2]));
}
};