这是我在编码挑战中遇到的一个有趣的问题:
有k个城市和n天。旅行社将在第n天向您展示城市k。您应该找到可以访问所有城市的最少天数。您也被允许不止一次访问城市,但理想情况下,您不希望这样做,因为您希望最大限度地减少天数。
输入:您获得了一系列日期和城市,其中天数是指数,城市是值。 A = [7,4,7,3,4,1,7]所以A [0] = 7意味着旅行社会在第0天显示城市7,在第1天显示城市4等。
所以,如果您从第0天开始,您将在第5天访问所有城市,但您也可以在第2天开始并在第5天结束。
输出:4因为至少花了4天时间访问所有城市
我的解决方案:我确实有一个O(N ^ 2)解决方案,可以尝试所有城市组合。但是测试说理想的时间和空间复杂度应该是O(N)。我该怎么做?
def findmin(A):
hashtable1={}
locationcount=0
#get the number of unique locations
for x in A:
if A[x] not in hashtable1:
locationcount+=1
index1=0
daycount=sys.maxint
hashtable2={}
#brute force
while index1<len(A):
index2=index1
prevday=index2
ans=0
count1=0
while index2<len(A):
if A[index2] not in hashtable2:
count1+=1
ans+=(index2-prevday)
hashtable2[A[index2]]=1
index2+=1
if count1==count:
daycount=min(ans,daycount)
hashtable2.clear()
index1+=1
return daycount+1
答案 0 :(得分:2)
这个问题可以通过双指针方法解决。
某些数据结构应包含当前窗口中的元素计数。也许你的哈希表是合适的。
将左右指针设置为列表的开头。
移动右指针,为这样的元素递增表条目:
hashtable2[A[rightindex]] = hashtable2[A[rightindex]] + 1
当所有(locationcount
)表条目变为非零时,停止向右移动指针。你有左右间隔覆盖所有城市。记住间隔长度。
现在移动左指针,递减表条目。当某些表条目变为零时,停止移动左指针。
再次移动右指针。重复直到列表结束。
请注意,索引只运行一次列表,复杂性是线性的(如果表条目更新为O(1),则哈希映射平均提供)
答案 1 :(得分:0)
我在面试中遇到了这个问题并且失败了,因为我想到移动窗户太晚了。几天后我拿了它,这是我的 C# 解决方案,我认为它是 O(n)(数组最多会被解析 2 次)。
我刷完之后剩下的难点是理解如何更新结束指针。可能有更好的解决方案,即使假期可以提前开始,我的解决方案也将始终提供尽可能高的开始和结束天数。
public int solution(int[] A) {
if (A.Length is 0 or 1) {
return A.Length;
}
var startingIndex = 0;
var endingIndex = 0;
var locationVisitedCounter = new int[A.Length];
locationVisitedCounter[A[0] - 1] = 1;
for (var i=1; i<A.Length; i++)
{
var locationIndex = A[i] - 1;
locationVisitedCounter[locationIndex]++;
if (A[i] == A[i - 1])
{
continue;
}
endingIndex=i;
while (locationVisitedCounter[A[startingIndex] - 1] > 1)
{
locationVisitedCounter[A[startingIndex] - 1]--;
startingIndex++;
}
}
return endingIndex - startingIndex + 1;
}
答案 2 :(得分:0)
Python 解决方案
`定义假期(A):
# Get all unique vacation locations
v_set = set(A)
a_l = len(A)
day_count = 0
# Maximum days to cover all locations will be the length of the array
max_day_count = a_l
for i in range(a_l):
count = 0
v_set_copy = v_set.copy()
# Starting point to find next number of days
#that covers all unique locations
for j in range(i, a_l):
# Remove from set, if the location exists,
# meaning we have visited the location
if (A[j] in v_set_copy):
v_set_copy.remove(A[j])
else:
pass
count = count + 1
# If we have visited all locations,
# determine the current minimum days needed to visit all and break
if (len(v_set_copy) == 0):
day_count = min(count, max_day_count)
max_day_count = day_count
break
return day_count`