最直接的思路是三层循环,但是会超时,代码如下:
1 public class Solution 2 { 3 public int LongestArithSeqLength2(int[] A) 4 { 5 var maxLength = 2; 6 var len = A.Count(); 7 for (var i = 0; i < len; i++) 8 { 9 for (var j = i + 1; j < len; j++) 10 { 11 var curmax = 2; 12 var target = A[i] - A[j]; 13 var next = A[j] - target; 14 for (var k = j + 1; k < len; k++) 15 { 16 if (A[k] == next) 17 { 18 curmax++; 19 next = A[k] - target; 20 } 21 22 } 23 maxLength = Math.Max(maxLength, curmax); 24 } 25 } 26 return maxLength; 27 } 28 }
但同样的代码,使用java实现,却可以正常提交,leetcode对这道题目的的判断机制有点奇怪。
如果想解决超时问题,可以考虑使用哈希或者dp思想,来减少判断的时间。
这种题目,做起来很麻烦,看看别人的思路吧。
当时没想出来怎么做,经过一段时间的练习(两个半月),重新做这道题目,顺利做出来了,说明练习还是有效果的。
给出一份python的实现:
1 class Solution: 2 def longestArithSeqLength(self, A: 'List[int]') -> int: 3 n = len(A) 4 if n == 2: 5 return 2 6 dic = {0:{0:1}} 7 longest = 0 8 for i in range(1,n): 9 if i not in dic: 10 dic[i] = {0:1} 11 for j in range(i): 12 diff = A[i] - A[j] 13 if diff not in dic[j]: 14 dic[i][diff] = 2 15 else: 16 dic[i][diff] = dic[j][diff] + 1 17 longest = max(longest,dic[i][diff]) 18 return longest
使用hash缓存之前的记录,从三层循环减少为两层循环,时间复杂度为O(n^2),但是增加了空间复杂度。典型的用空间换时间的思想。
dic是一个字典,key值是数组的下标,value值是一个字典类型。
这个value字典,key值是int类型,表示两项之间的差;value值是int类型,表示这个差值形成的等差数列的长度。
因此每次循环用longest记录任意一个差值所形成的最长的等差数列的长度,即为所求。