题意整理
- 给定一个一维数轴,起点在原点,每次可以向左或者向右移动0或3或7或11个单位。
- 为了移动到目标点target,计算最少的移动次数。
- 输入对应的target坐标集合,返回对应的移动次数集合。
方法一(动态规划)
1.解题思路
- 首先计算移动到范围内的目标点对应的最少移动次数。
- 初始化dp数组。
- 由于范围内的所有情况都统计了,目标点在大于11的范围时,只需从之前的点后移3位、7位或者11位,不用再左移了(所有的点都能通过右移到达,左移会增加移动次数)。所以状态转移方程是:。
- 根据状态转移方程,计算所有可能的情况,然后将dp数组对应的移动次数赋值到结果数组。
计算范围内目标点的过程:
0, // 目标点为0,无需移动
3, // 目标点为1,1=7-3-3
4, // 目标点为2,2=7+3+3-11
1, // 目标点为3,3=3
2, // 目标点为4,4=7-3
3, // 目标点为5,5=11-3-3
2, // 目标点为6,6=3+3
1, // 目标点为7,7=7
2, // 目标点为8,8=11-3
3, // 目标点为9,9=3+3+3
2, // 目标点为10,10=7+3
1, // 目标点为11,11=11
测试数据较大时,会超过内存限制。
2.代码实现
import java.util.*; public class Solution { /** * 把所有询问的答案按询问顺序放入vector里 * @param arr int整型一维数组 要查询坐标的数组 * @return int整型一维数组 */ public int[] MinimumTimes (int[] arr) { int n=arr.length; //初始化结果数组以及终点在0-11某一处时对应的移动次数 int[] res=new int[n]; int[] init=new int[]{0,3,4,1,2,3,2,1,2,3,2,1}; int max=-1; //求最大值 for(int i=0;i<n;i++){ max=Math.max(max,arr[i]); } //初始化dp数组 int[] dp=new int[max+1]; for(int i=0;i<=max;i++){ if(i<12){ dp[i]=init[i]; } //状态转移 else{ dp[i]=Math.min(dp[i-3],Math.min(dp[i-7],dp[i-11]))+1; } } //赋值给结果数组 for(int i=0;i<n;i++){ res[i]=dp[arr[i]]; } return res; } }
3.复杂度分析
- 时间复杂度:所有的循环均为线性遍历,假设arr数组最大值为max,所以最终的时间复杂度为。
- 空间复杂度:需要额外大小为max的dp数组,所以空间复杂度为。
方法二(数学)
1.解题思路
将方法一中dp数组的前78个数,打印出来可得:
0--3--4--1--2--3--2--1--2--3--2--1 4--3--2--3--4--3--2--3--4--3--2 5--4--3--4--5--4--3--4--5--4--3 6--5--4--5--6--5--4--5--6--5--4 7--6--5--6--7--6--5--6--7--6--5 8--7--6--7--8--7--6--7--8--7--6 9--8--7--8--9--8--7--8--9--8--7
可以发现除了第0项以及第2项,之后的每一行都由前一行对应项加一所得。
- 初始化结果数组以及init数组。
- 遍历arr数组,如果是第二项,直接返回4。
- 每隔11个数,由第一行对应的数加上行号即可得到当前项的值。
动图展示:
2.代码实现
import java.util.*; public class Solution { /** * 把所有询问的答案按询问顺序放入vector里 * @param arr int整型一维数组 要查询坐标的数组 * @return int整型一维数组 */ public int[] MinimumTimes (int[] arr) { int n=arr.length; //初始化结果数组以及终点在0-11某一处时对应的移动次数 int[] res=new int[n]; int[] init=new int[]{0,3,2,1,2,3,2,1,2,3,2,1}; for(int i=0;i<n;i++){ //特殊点 if(arr[i]==2){ res[i]=4; continue; } //每隔11个数,由第一行对应的数加上行号 res[i]=arr[i]/11+init[arr[i]%11]; } return res; } }
3.复杂度分析
- 时间复杂度:需要遍历arr数组一次,所以时间复杂度为。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度为。