- 如果nums[i] >= nums[i - 1],我们排除掉的所有数都是小于等于nums[i - 1],自然也小于等于nums[i]的,不是我们要找的数
- 如果nums[i] < nums[i - 1],那么nums[i]对应要找的数就是nums[i - 1]
所以我们如果从右向左扫描,维护一个从左向右的递增序列。对于nums[i],我们pop所有栈顶小于等于nums[i]的数。这些数就是我们上面所说的不需要考虑的数,如果此时栈顶还有元素,那就是我们要找的nums[i]对应的数,否则,i的右边不存在比nums[i]更大的数。这道题要求距离,我们存index即可。时间复杂度O(n),空间复杂度O(n),代码如下:
另一种方法,因为我们直接利用我们要return的数组next,next记录了对于每个nums[i]其右边大于nums[i]最近的数的距离。那么对于nums[i]来说,有两种情况:
- nums[i] < nums[i + 1],next[i] = 1
- nums[i] >= nums[i + 1],我们找到nums[i + 1 + next[i + 1]],这个是满足条件的对应nums[i + 1]的数,所有在(i + 1, i + 1 + next[i + 1])都可以根据我们之前的分析排除。继续用nums[i + 1 + next[i + 1]]和nums[i]比较,直到我们找到满足条件的数或者发现找不到
这个做法的时间复杂度显然不是O(n^2),因为对于nums[i],如果我们要一路回溯到最右端,那么[i + 1, len - 1]一定是一个递增序列,并且nums[i + 1] <= nums[i], nums[i] >= nums[len - 1]。那么这个递增序列,每一个数要向右找一位,假设[i, len - 1]长度为m,所以每一次yamotized time为(m - 1 + m - 1) / m = O(1)。那么对于nums来说,我们可以把其切分成不同的这样的序列,这样总的时间复杂度依然是O(n)。空间复杂度,不考虑return数组要开的空间,我们没有用额外的空间。代码如下:
No comments:
Post a Comment