求解 python 面试题:
def solution(A):
N = len(A)
result = 0
for i in xrange(N):
for j in xrange(N):
if A[i] == A[j]:
result = max(result, abs(i - j))
return result
当数组极大时,效率不好,求如何改??!!
1
holajamc 2017-07-11 13:49:53 +08:00 1
这……不永远都是 0 么…
|
2
capbone 2017-07-11 13:51:36 +08:00 1
计算相距最远的两个相等元素?
先用 argsort 返回排序序号,再分组求最大值,应该会高效不少吧? |
5
capbone 2017-07-11 13:53:45 +08:00
没... 我也只是随便一想给了个大概思路...
|
7
shuson 2017-07-11 13:59:42 +08:00
```
def sol(A): n = len(A) for i in range(n): j = n-1 while j > i: if A[i] == A[j]: return j - i j -= 1 return 0 ``` |
8
geelaw 2017-07-11 14:03:39 +08:00 2
用字典和合适的 hash 函数族可以做附加空间 O(n),期望时间 O(n) 的。
用排序可以做附加空间 O(n),时间 O(nlogn) 的。 |
10
holyghost 2017-07-11 14:06:16 +08:00 1
hashmap 记录第一次出现该元素的 index
后面就是更新 max = (currentIndex - index) 了 空间 O(n) 时间 O(n) |
11
shuson 2017-07-11 14:07:01 +08:00
|
12
tkpc 2017-07-11 14:08:51 +08:00
V = {}
for i,x in enumerate(A): if x in V: V[x][1] = i else: V[x] = [i,i] print max( (b-a) for a,b in V.itervalues() ) |
13
Valyrian 2017-07-11 14:14:15 +08:00
难道不是直接 return max(A) - min(A)
|
14
csdreamdong 2017-07-11 14:14:47 +08:00
0 0 我果然还是菜。。真心求问。这题想描述什么问题。
|
16
yunkchen 2017-07-11 14:18:55 +08:00
import collections
def solution(A): l_count = collections.Counter(A) repeats = [k for k, v in l_count.items() if v > 1] ix_dict = collections.defaultdict(lambda: set()) for i in range(len(A)): if A[i] in repeats: ix_dict[A[i]].add(i) return max([max(ix_value)-min(ix_value) for ix_value in ix_dict.values()]) |
17
chroming 2017-07-11 14:29:34 +08:00
一个小优化
''' def solution(A): N = len(A) result = 0 for i in xrange(N): for j in xrange(i, N): if A[i] == A[j]: result = max(result, abs(i - j)) return result ''' |
18
chroming 2017-07-11 14:30:27 +08:00
回复怎么不支持 markdown 了
把 for j in xrange(N)改成 for j in xrange(i, N): |
19
gimp 2017-07-11 14:35:11 +08:00
|
20
ty89 2017-07-11 14:35:34 +08:00
```
def foo(a): m = {} max_delta = 0 for current_index in xrange(len(a)): s = a[current_index] if not m.has_key(s): m[s] = {'first_index':current_index} delta = 0 else: delta = abs(m[s]['first_index'] - current_index) max_delta = max(max_delta, delta) return max_delta ``` |
21
ty89 2017-07-11 14:38:00 +08:00
悲剧,评论吞代码
![]( ) |
22
takeoffyoung 2017-07-11 15:03:41 +08:00
|
23
takeoffyoung 2017-07-11 15:04:42 +08:00
|
24
di94sh 2017-07-11 15:15:32 +08:00
这样时间复杂度是不是 O(N)
[Imgur]( http://imgur.com/a/zTNYd) |
25
di94sh 2017-07-11 15:16:08 +08:00
|
26
Yvette 2017-07-11 15:45:32 +08:00
|
27
zlin3000 2017-07-11 16:27:49 +08:00 via Android
因为是求最远相同元素距离,感觉可以从最远距离直接下手,即最大的可能最远距离只有一种,即第一个元素和最后一个元素,下一层可能得到最远距离的是两种即第一个和倒数第二个,第二个和倒数第一个,然后以此类推。
|
29
aaronzjw 2017-07-11 16:31:49 +08:00 via Android
考虑下哪些元素重复,然后对重复的元素进行计算
|
30
zlin3000 2017-07-11 16:40:51 +08:00 via Android
这么一说,如果不考虑空间成本的情况下,时间应该是 O(n),遍历数组,用字典记住每个元素出现的最初位置,然后一个 max value 记入当前最远距离。
|
31
aaronzjw 2017-07-11 16:49:07 +08:00
|
32
QAPTEAWH 2017-07-11 17:56:04 +08:00 1
动态规划
D(i,j) = j - i, if item[i] = item[j], or max{D(i+1, j), D(i, j-1)} |
33
cxyfreedom 2017-07-11 18:27:48 +08:00
```
max([(len(l) - l[::-1].index(i) - 1) - l.index(i) for i in set(l)]) ``` |
34
sky101001 2017-07-11 19:11:11 +08:00 via iPad
第一反应是排序复杂度是 O(nlogn),再比较相邻元素,复杂度是 O(n),选出最大间隔 O(nlogn)。最终时间复杂度可以是 O(nlogn)。
不过总觉得有更快的方法,容我想想 |
36
ArcticL 2017-07-12 14:24:43 +08:00
@zlin3000 有一点是当 result 越小,甚至等于 0 时,时间成本比原方案更大
def solution(A): arrayLength = len(A) for result in range(arrayLength, -1, -1): for i in range(arrayLength): if i + result < arrayLength and A[i] == A[i + result]: return result |
37
zlin3000 2017-07-12 18:07:18 +08:00
@ArcticL
原方案时间复杂度 是 固定的 O ( n^2 ) 我的第一个方案,最差 case 是 O ( n^2 ),1 + 2 + 3 + 4 + 5 + ... + n-1 = (n*(n-1))/2 所以 时间成本并不会比原方案更大。 |
39
zlin3000 2017-07-13 01:58:51 +08:00
@ArcticL 代码:
```python def solution(A): # 两个元素之间的可能最长距离为数组长度-1 max_dist = len(A) - 1 # 从最长距离开始逐渐往下递减 for dist in range(max_dist, 0, -1): # 因为是按距离长度查找, 固每次只要查看可能可以达成当前长度距离的数组 # 所以第一次只能是 第一个元素和最后一个元素; # 第二次是第一个和倒数第二个, 第二个和最后一个元素; 第三次可以此类推 # 因此是 1 + 2+ 3 + ... + n-1 for i in range(len(A) - dist): if A[i] == A[i+dist]: return dist # 如果循化结束没有答案,则表示没有匹配数组 return 0 ``` |
41
719465553 2019-01-24 14:44:41 +08:00
新建一个数组放下标,快排之后一个 for 算下标差就好了
|