这一天的面试值得记录一下
算法题是leetcode 1214
这个题目我首先写了一个nlogn的算法,在左边树上迭代,右边树上查找目标值
接下来的问题是,如何进行优化?
显然nlogn的下一个目标是n.因为nlogn在常数级上已经没有优化空间了
然后n的方法我起初看着两颗树是没有想到的,后来还是面试官提示了一下说,两个有序数组怎么做
确实,两个二叉搜索树,其实就是可以简化成两个有序数组做。
如果两个有序数组,n的时间,估计就是双指针呗。不过这都是方向的猜测,具体到方法上,还是有细节需要思考的。到这里的时候其实面试官提示了很多了,不过我经常面试的时候脑子一片空白,当时完全无法继续思考了。
比如,第一步,我们可能根据经验,会想出一个双指针的做法,小了左指针右移,大了右指针左移。但是具体到为什么这样做是ok的,还是要给个证明,现在将证明总结如下:
如果走到[i,j]这个位置了
那么当前任何[i+1,j],[i+2,j]...都大于[i,j].
任何[i,j+1],[i,j+2],...都小于[i,j].
任何[i-1,j],[i-2,j],...都小于[i,j].
任何[i,j-1],[i,j-2],...都大于[i,j].
所以对于[i,j]来说,如果当前和小于t,我们要增大和,就将坐标往右。但是这里不能往上走了,为什么呢?
因为对于处在[i,j]上方而大于[i,j]的这些值,是我们之前就判断过的,之前走的路径,一种是由正上方直接向下走,走到[i,j],在这种情况下说明之前判断的时候发现和大于t了,所以需要减小。另一种路径是从正上方的左侧向下走,然后再向右走。这种情况下是当时处在和正上方某个值同一纵坐标位置时,和大于t,也需要减小,所以向下走,而没有向右走。
可见,这种方法是可行的。
如果对于图中其他位置的判断过程,也可以做如上所述的分析。
这样的一种路径使得时间复杂度是O(m+n).
除此以外,还可以从两个循环,O(N^2)的角度来一步步优化,具体代码我已经在leetcode提交了,看提交记录