[英]Optimizing python code - searching within an unsorted list with nested loops as index positions need to be retained
I have a list (stockData) with some random positive integers then another query list (queries) that contains some positions(indexes counted from 1 and not 0) within stockData.我有一个包含一些随机正整数的列表(stockData),然后是另一个查询列表(查询),其中包含 stockData 中的一些位置(从 1 开始计数的索引而不是 0)。
Based on the 'queries', The code must identify a closest value smaller than the one at a give position.基于“查询”,代码必须识别一个最接近的值,该值小于给定 position 的值。 If there is a clash/tie, the smaller index position is preferred.
如果存在冲突/平局,则首选较小的索引 position。 If no such value can be identified on either side of position, then -1 should be returned.
如果在 position 的任一侧都无法识别出此类值,则应返回 -1。
Example1示例 1
stockData = [5,6,8,4,9,10,8,3,6,4]
queries = [6,5,4]
At position 6 (index=5) in stockData, value is 10, both position 5 (index=4) and position 7 (index=6) are smaller values (9 and 8 resp.) than 10, hence we choose the one at a lesser position -> [5]
At position 5 (index=4) in stockData, value is 9, position 4 (index=3) is smaller hence we choose position 4 -> [5,4]
At position 4 (index=3) in stockData, value is 4, position 8 (index=7) is only value smaller hence we choose position 8 -> [5,4,8]
Output
[5,4,8]
Example2示例 2
stockData = [5,6,8,4,9,10,8,3,6,4]
queries = [3,1,8]
Here, at position 8, the value 3 is the smallest of the list, so we return -1
Output
[2,4,-1]
Constraints约束
1 <= n <= 10^5 (n is the length of stockData)
1 <= stockData[i] <= 10^9
1 <= q <= 10^5 (q is the length of queries)
1 <= queries[i] <= 10^9
My code is working fine, but taking too long to execute.我的代码运行良好,但执行时间过长。 Looking for any help with optimizing it or any other corrective measures.
寻求优化它或任何其他纠正措施的任何帮助。 Thanks !!
谢谢 !!
My Code:我的代码:
def predictAnswer(stockData, queries):
# convert days to index
query_idx = [val-1 for val in queries]
# output_day_set
out_day = []
for day in query_idx:
min_price = stockData[day]
day_found = False
for i in range(1, max(day,len(stockData)-day)):
prev = day-i
nxt = day+i
if prev >= 0 and stockData[prev] < min_price:
out_day.append(prev+1)
day_found = True
break
if nxt < len(stockData) and stockData[nxt] < min_price:
out_day.append(nxt+1)
day_found = True
break
if not day_found:
out_day.append(-1)
return out_day
Solution Approach as suggested by @Carlos: @Carlos 建议的解决方案方法:
for idx, val in enumerate(stockData):
if val in stockDict.keys():
stockDict[val].append(idx)
else:
stockDict[val] = [idx]
stockDict_sortedKeys = sorted(stockDict)
For the sample input:对于样本输入:
stockData = [5,3,4,6,5,4,6,8,9,5,7]
Output: Output:
stockDict = {5: [0], 6: [1, 8], 8: [2, 6], 4: [3, 9], 9: [4], 10: [5], 3: [7]}
stockDict_sortedKeys = [3, 4, 5, 6, 8, 9, 10]
Now may be for a for a given query 'day', I would need to find the corresponding sortedData[day] and find the closest index for all the values smaller?现在可能是对于给定查询'day',我需要找到相应的 sortedData[day] 并找到所有值更小的最近索引?
You can iterate on your stockData
to get the most recent previous smaller value, by keeping a heap of local minima:您可以通过保持一堆局部最小值来迭代您的
stockData
以获得最近的先前较小的值:
import heapq
class Data:
def __init__(self, day, value):
self.day = day
self.value = value
def __lt__(self, other):
return self.value >= other.value
def __repr__(self):
return f'Data(day={self.day}, value={self.value})'
def precalc(days):
result = []
heap = []
for day, value in days:
data = Data(day, value)
while heap and heap[0] < data:
heapq.heappop(heap)
result.append(heap[0].day if heap else -1)
heapq.heappush(heap, data)
return result
The complexity is O(n log(n))
, as each day can only be pushed/popped once.复杂度为
O(n log(n))
,因为每天只能推送/弹出一次。
To get the expected answer, you have to do it in the other direction also:要获得预期的答案,您还必须朝另一个方向进行:
def compare(f, b, q):
if f < 0: return b
if b < 0: return f
if q-f <= b-q:
return f
else:
return b
def predictAnswer(stockData, queries):
forward = precalc(enumerate(stockData, 1))
backward = list(reversed(precalc(reversed(list(enumerate(stockData, 1))))))
return [compare(forward[q-1], backward[q-1], q) for q in queries]
This is still O(n log(n))
.这仍然是
O(n log(n))
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.