贴个自己的解法, 时间复杂度是O(KN)而非O(KNL)
另外感谢kaipeng21的test cases
Time complexity: O(KN)
Space complexity: O(KL)
N: street長度
K: requirements長度
L: 同一個requirement在*不同*index上出現的最大次數
- import collections
- from typing import List
- class Interview(object):
- def solution(self, street: List[List[str]], requirements: List[str]) -> int:
- dists = {}
- road_map = collections.defaultdict(collections.deque)
- # Builds the road map.
- for i, location in enumerate(street):
- for facility in set(location): # Note: use `set` to deduplicate.
- if facility in requirements:
- road_map[facility].append(i)
-
- for facility in requirements:
- # Adds additional two ends to avoid some annoying if statements.
- road_map[facility].appendleft(float('-inf'))
- road_map[facility].append(float('inf'))
- dists[facility] = float('inf')
- index = -1 # Returns -1 if no solution exists.
- dist_sum = float('inf')
- for i in range(len(street)):
- # Updates minimum distances
- for facility in requirements:
- left, right = road_map[facility][0], road_map[facility][1]
- dists[facility] = min(i - left, right - i)
- if i == right:
- road_map[facility].rotate(-1) # Rotates one step left.
-
- # Updates the best location.
- current_sum = sum(dists.values())
- if current_sum < dist_sum:
- dist_sum = current_sum
- index = i
-
- return index
- # Don't specify return value if it's None.
- test_cases = [
- [
- ["Store", "School", "Museum"],
- ["Hospital", "Restaurant"],
- ["School", "Restaurant"],
- ],
- ["Store", "Museum", "Hotel"],
- -1,
- [
- ["Store", "School", "Museum"],
- ["Hospital", "Restaurant"],
- ["School", "Restaurant"],
- [],
- ["Museum"],
- ],
- ["Store", "Museum", "Restaurant"],
- 0,
- #
- [
- ["Store", "School", "Museum"],
- ["Hospital", "Restaurant"],
- ["School", "Restaurant"],
- [],
- ["Museum"],
- ],
- ["Hospital", "Restaurant"],
- 1,
- #
- [
- ["Store", "School", "Museum"],
- ["Hospital", "Restaurant"],
- ["School", "Restaurant"],
- [],
- ["Museum"],
- ],
- ["Museum", "Hospital"],
- 0,
- ###
- [
- ["School", "Store", "School"],
- ["Park"],
- [],
- ["Restaurant"],
- ["Hospital"],
- ],
- ["Park","Restaurant"],
- 1,
- #
- [
- ["School", "Store", "School"],
- ["Park"],
- [],
- ["Restaurant"],
- ["Hospital"],
- ],
- ["School","Restaurant"],
- 0,
- #
- [
- ["School", "Store", "School"],
- ["Park"],
- [],
- ["Restaurant"],
- ["Hospital"],
- ],
- ["Hospital"],
- 4,
- ###
- [
- ["A", "B", "C"],
- ["D", "E", "F"],
- ["G", "H"],
- ["I", "J", "K"],
- ["L", "M", "N"],
- ["O", "P", "Q", "R", "S", "T", "U", "V"],
- ["W", "X", "Y"],
- [],
- ["Z"],
- ],
- ["F", "K"],
- 1,
- #
- [
- ["A", "B", "C"],
- ["D", "E", "F"],
- ["G", "H"],
- ["I", "J", "K"],
- ["L", "M", "N"],
- ["O", "P", "Q", "R", "S", "T", "U", "V"],
- ["W", "X", "Y"],
- [],
- ["Z"],
- ],
- ["A", "Z"],
- 0,
- #
- [
- ["A", "B", "C"],
- ["D", "E", "F"],
- ["G", "H"],
- ["I", "J", "K"],
- ["L", "M", "N"],
- ["O", "P", "Q", "R", "S", "T", "U", "V"],
- ["W", "X", "Y"],
- [],
- ["Z"],
- ],
- ["C", "V", "Z"],
- 5,
- ###
- [
- ["A", "B", "C"],
- ["F"],
- [],
- ["D", "E"],
- [],
- [],
- [],
- ["D", "E"],
- [],
- [],
- ["C", "B", "A"]
- ],
- ["A", "E"],
- 0,
- #
- [
- ["A", "B", "C"],
- ["F"],
- [],
- ["D", "E"],
- [],
- [],
- [],
- ["D", "E"],
- [],
- [],
- ["C", "B", "A"]
- ],
- ["F", "A"],
- 0,
- #
- [
- ["A", "B", "C"],
- ["F"],
- [],
- ["D", "E"],
- [],
- [],
- [],
- ["D", "E"],
- [],
- [],
- ["C", "B", "A"]
- ],
- ["D", "E"],
- 3,
- ###
- [
- ["A", "B", "C"],
- [],
- [],
- ["D", "E"],
- ["F", "G", "H"],
- ["I", "J", "K"],
- ["L"],
- ["M"],
- ["E"],
- ["N"]
- ] * 3,
- ["A", "D"],
- 0,
- #
- [
- ["A", "B", "C"],
- [],
- [],
- ["D", "E"],
- ["F", "G", "H"],
- ["I", "J", "K"],
- ["L"],
- ["M"],
- ["E"],
- ["N"]
- ] * 3,
- ["D", "M"],
- 3,
- #
- [
- ["A", "B", "C"],
- [],
- [],
- ["D", "E"],
- ["F", "G", "H"],
- ["I", "J", "K"],
- ["L"],
- ["M"],
- ["E"],
- ["N"]
- ] * 3,
- ["B", "N"],
- 9,
- #
- [
- ["A", "B", "C"],
- [],
- [],
- ["D", "E"],
- ["F", "G", "H"],
- ["I", "J", "K"],
- ["L"],
- ["M"],
- ["E"],
- ["N"]
- ] * 3,
- ["E", "F", "M"],
- 4,
- ]
- if __name__ == '__main__':
- interview = Interview()
- args_count = Interview.solution.__code__.co_argcount - 1 # - 1 for self.
-
- args = []
- iterator = iter(test_cases)
- while True:
- try:
- args.append(next(iterator))
- except StopIteration:
- break
- if len(args) == args_count:
- result = interview.solution(*args)
- if result is not None:
- try:
- answer = next(iterator)
- assert result == answer
- except AssertionError:
- print(f'Input:')
- for arg in args:
- print(f'\t{arg}')
- print(f'Expected: {answer}')
- print(f'Your output: {result}')
- args = []
- print('End.')
复制代码
补充内容 (2019-3-31 02:21):
忘记设限制
没办法删文的吗?
补充内容 (2019-3-31 02:24):
解释一下
概念就是最初就纪录各requirements的位置
之后利用deque只比较最接近的两个
为了方便只回传符合要求的最小index
follow-up直接对没有apartment的index给continue就好了 |