给定一个数组,找到一个子数组,其中元素的乘积等于N. 这是我的尝试
P = 1
Make an another array arr1
for i = 0 to n-1
arr1[i] = P
P *= arr1[i]
put elements, index of arr1 in hash table
for i = 0 to n-1
search in hash table for P/arr1[i]
if found
return [i+1 ... index in hash table]
这是对的吗?任何其他更简单的解决方案。
答案 0 :(得分:4)
它可以在O(n)时间和O(1)存储器中解决,只需要2个额外的指针和当前产品。想法是使用滑动窗口。保留两个指针,p1和p2。最初它们都指向数组的第一个元素,乘积等于1.虽然乘积小于n然后向右移动p2并在p2处逐个元素乘以。当你达到n或更多:如果product == n返回p1和p2,否则向右移动p1并重复它直到p2到达数组的末尾。
答案 1 :(得分:1)
你的解决方案基本上是合理的。它很简单并且具有O(n)
时间复杂度(假设哈希表插入和查找都是O(1)
)。因为在最坏的情况下,任何解决方案都需要至少检查一次每个元素,O(n)
就像你能得到的一样好。
关于分工有两个问题:
P/arr1[i]
表示N/arr1[i]
。if
声明,以确保N
可以被arr1[i]
整除。另外,我认为你的索引可能搞砸了,但我现在没时间详细检查它。
答案 2 :(得分:1)
Artem Volkhin's answer建议的滑动窗口算法具有O(n)
复杂度。
O(n)
,单程。def sliding_window(seq, n):
low,high=0,0 # Low index, High index
cur_sum=seq[low]
while high<=len(seq):
if cur_sum==n: # Match found, return indices
return low, high
elif cur_sum<n: # Sum to low, increase high index
high+=1
cur_sum*=seq[high]
else:
cur_sum/=seq[low] # Sum to high, increase low index
low+=1
return None, None # No match, Return
>>> ls=range(1,11)
>>> print ls
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>>
>>> N=336 # 6*7*8
>>> print sliding_window(ls, N)
(5, 7) # Indices
答案 3 :(得分:0)
(在c ++中):
// returns true if found and sub-array indices in low & high, false otherwise
bool findprod(int arr[], int size, int N, int& low, int& high)
{
int prod = 1;
for (low = high = 0; high < size; ++high) {
prod *= arr[high];
if (prod < N) continue;
if (prod > N)
for (; prod > N && low <= high; ++low)
prod /= arr[low];
if (prod == N) break; // found
}
return high < size;
}
(与我看到的@Artem相同的解决方案)