classSolution: defminTaps(self, n: int, ranges: List[int]) -> int: intervals = [] for i, r inenumerate(ranges): start = max(0, i - r) end = min(n, i + r) intervals.append((start, end)) intervals.sort()
dp = [inf] * (n + 1) dp[0] = 0 for start, end in intervals: if dp[start] == inf: return -1 for j inrange(start, end + 1): dp[j] = min(dp[j], dp[start] + 1) return dp[n]
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
constint INF = 0x3f3f3f3f;
staticintcmp(constvoid *pa, constvoid *pb) { int la = ((int *)pa)[0], ra = ((int *)pa)[1]; int lb = ((int *)pb)[0], rb = ((int *)pb)[1]; if (la == lb) { return ra - rb; } return la - lb; }
intminTaps(int n, int* ranges, int rangesSize) { int seglines[n + 1][2]; for (int i = 0; i <= n; i++) { seglines[i][0] = MAX(0, i - ranges[i]); seglines[i][1] = MIN(n, i + ranges[i]); } qsort(seglines, n + 1, sizeof(seglines[0]), cmp); int dp[n + 1]; memset(dp, 0x3f, sizeof(dp)); dp[0] = 0; for (int i = 0; i <= n; i++) { int start = seglines[i][0]; int end = seglines[i][1]; if (dp[start] == INF) { return-1; } for (int j = start; j <= end; j++) { dp[j] = MIN(dp[j], dp[start] + 1); } } return dp[n]; }
classSolution { public: intminTaps(int n, vector<int>& ranges){ vector<int> rightMost(n + 1); iota(rightMost.begin(), rightMost.end(), 0); for (int i = 0; i <= n; i++) { int start = max(0, i - ranges[i]); int end = min(n, i + ranges[i]); rightMost[start] = max(rightMost[start], end); } int last = 0, ret = 0, pre = 0; for (int i = 0; i < n; i++) { last = max(last, rightMost[i]); if (i == last) { return-1; } if (i == pre) { ret++; pre = last; } } return ret; } };
publicclassSolution { publicintMinTaps(int n, int[] ranges) { int[] rightMost = newint[n + 1]; for (int i = 0; i <= n; i++) { rightMost[i] = i; } for (int i = 0; i <= n; i++) { int start = Math.Max(0, i - ranges[i]); int end = Math.Min(n, i + ranges[i]); rightMost[start] = Math.Max(rightMost[start], end); } int last = 0, ret = 0, pre = 0; for (int i = 0; i < n; i++) { last = Math.Max(last, rightMost[i]); if (i == last) { return-1; } if (i == pre) { ret++; pre = last; } } return ret; } }
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
intminTaps(int n, int* ranges, int rangesSize) { int rightMost[n + 1]; memset(rightMost, 0, sizeof(rightMost)); for (int i = 0; i <= n; i++) { int start = MAX(0, i - ranges[i]); int end = MIN(n, i + ranges[i]); rightMost[start] = MAX(rightMost[start], end); } int last = 0, ret = 0, pre = 0; for (int i = 0; i < n; i++) { last = MAX(last, rightMost[i]); if (i == last) { return-1; } if (i == pre) { ret++; pre = last; } } return ret; }
var minTaps = function(n, ranges) { const rightMost = newArray(n + 1).fill(0).map((_, i) => i); for (let i = 0; i <= n; i++) { const start = Math.max(0, i - ranges[i]); const end = Math.min(n, i + ranges[i]); rightMost[start] = Math.max(rightMost[start], end); } let last = 0, ret = 0, pre = 0; for (let i = 0; i < n; i++) { last = Math.max(last, rightMost[i]); if (i === last) { return -1; } if (i === pre) { ret++; pre = last; } } return ret; };
funcminTaps(n int, ranges []int)int { rightMost := make([]int, n+1) for i := range rightMost { rightMost[i] = i } for i, r := range ranges { start := max(0, i-r) end := min(n, i+r) rightMost[start] = max(rightMost[start], end) }
last, ret, pre := 0, 0, 0 for i := 0; i < n; i++ { last = max(last, rightMost[i]) if i == last { return-1 } if i == pre { ret++ pre = last } } return ret }
funcmin(a, b int)int { if a > b { return b } return a }
funcmax(a, b int)int { if b > a { return b } return a }
复杂度分析
时间复杂度:O(n),其中 n 表示给定的数字 n。我们需遍历 ranges 数组一遍,然后再遍历 [0,n] 每个位置,因此时间复杂度为 O(n)。
空间复杂度:O(n),其中 n 表示给定的数字 n。保存每个位置 i\in[0,n] 为起点的子区间的右端点的最大值,需要的空间为 O(n),因此总的空间复杂度为 O(n)。