1. 套路1:
一般这种数对,还涉及排序的,根据第一个元素正向排序,根据第二个元素反向排序,或者根据第一个元素反向排序,根据第二个元素正向排序,往往能够简化解题过程。
比如这些题目:
2. 技巧2: 成环的题目对于索引的控制:i%len
比如:
134. 加油站
圆环回原点问题
题目描述:圆环上有10个点,编号为0~9。从0点出发,**每次可以逆时针和顺时针走一步,问走n步回到0点共有多少种走法。**举例:
- 如果n=1,则从0出发只能到1或者9,不可能回到0,共0种走法
- 如果n=2,则从0出发有4条路径:0->1->2, 0->1->0, 0->9->8, 0->9->0,其中有两条回到了0点,故一共有2种走法
类似与爬楼梯缩小规模的思路,爬上n阶楼梯 = 爬上n-1阶楼梯数+爬上n-2阶楼梯数
走
n步到0的方案数 = 走n-1步到1的数 + 走n-1步到9的数
dp[i][j] = 走i步到j的方案数, = 走i-1步到j-1处的数 + 走i-1到j+1处的数
但是因为是○,所以通过取余来避免越界,(j-1+len)%len,(j+1)%len====>防止越界的思想可以好好学习
dp[i][j] = dp[i-1][(j-1+len)%len]+dp[i-1][(j-1)%len]
public int circlePath(int step,int len){
// 特殊情况的排除
if(len==0){
return 1;
}
if(len==2){
return step%2==0?1:0;
}
// 1.dp[i][j]表示走i步到达j的方法数,所以i<step+1,j<len
int[][] dp = new int[step+1][len];
// 2.对于特殊情况的处理
dp[0][0] = 1;
for (int i = 1; i <= step; i++) {
for (int j = 0; j < len; j++) {
dp[i][j] = dp[i-1][(j-1+len)%len] + dp[i-1][(j+1)%len];
}
}
return dp[step][0];
}

这篇博客分享了两种常见的算法解题技巧。第一种是涉及数对排序的问题,可以通过调整第一个和第二个元素的排序方向简化解题。例如在406.根据身高重建队列、452.用最少数量的箭引爆气球等题目中适用。第二种技巧是处理环形结构时利用索引的模运算,如134.加油站和圆环问题,通过(i%len)避免边界错误。博客通过一个例子详细解释了如何利用动态规划解决走n步回到0点的问题,并展示了如何构建状态转移方程。
1717

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



