难度指数:⭐⭐⭐⭐
知识点:单向栈
通用一般算法:
华为od统一考试B卷【阿里巴巴找黄金宝箱(IV)】Python 实现https://renjie.blog.csdn.net/article/details/130962068
def solve():
n = len(nums)
ret = [-1] * n
stk = list()
for i in range(n * 2 - 1):
while stk and nums[stk[-1]] < nums[i % n]:
ret[stk.pop()] = nums[i % n]
stk.append(i % n)
return ret
创新算法
idea
- 现有算法在将环断开时具有一定未知性,于是遍历两次;
- 该算法从最大值处开始遍历,突破了未知。
代码实现
def solve0():
m = max(nums)
stack = [m]
s = nums.index(m)
res = [-1] * len(nums)
for i in range(s - 1, s - len(nums), -1):
while nums[i] >= stack[-1] and stack[-1] != m:
stack.pop()
if nums[i] != stack[-1]:
res[i] = stack[-1]
stack.append(nums[i])
return res
对比验证
耗时:
from time import time
import random
def solve():
n = len(nums)
ret = [-1] * n
stk = list()
for i in range(n * 2 - 1):
while stk and nums[stk[-1]] < nums[i % n]:
ret[stk.pop()] = nums[i % n]
stk.append(i % n)
return ret
def solve0():
m = max(nums)
stack = [m]
s = nums.index(m)
res = [-1] * len(nums)
for i in range(s - 1, s - len(nums), -1):
while nums[i] >= stack[-1] and stack[-1] != m:
stack.pop()
if nums[i] != stack[-1]:
res[i] = stack[-1]
stack.append(nums[i])
return res
T = 10
while T:
nums = [random.randint(-1e5, 1e5) for _ in range(random.randint(1, 1e4))]
t1 = time()
res = solve()
t2 = time()
res0 = solve0()
t3 = time()
if res != res0:
print(','.join(map(str, res)))
print(','.join(map(str, res0)))
print(t2 - t1, t3 - t2)
T -= 1