原题
You are given an array x of n
positive numbers. You start at point (0,0)
and moves x[0]
metres to the north, then x[1]
metres to the west, x[2]
metres to the south,x[3]
metres to the east and so on. In other words, after each move your direction changes counter-clockwise.
Write a one-pass algorithm with O(1)
extra space to determine, if your path crosses itself, or not.
Example1
Given x = [2, 1, 1, 2], ┌───┐ │ | └───┼──> │ Return true (self crossing)
Example2
Given x = [1, 2, 3, 4], ┌──────┐ │ │ │ │ └────────────> Return false (not self crossing)
Example3
Given x = [1, 1, 1, 1], ┌───┐ │ │ └───┼> Return true (self crossing)
简介
一看到这个题目的时候,我暗自窃喜,这题目也太简单了吧,只需要x[2]的长度大于等于x[0],x[3]的长度大于等于x[1]的长度。另外题目给出的路径只有x[0],x[1],x[2],x[3],再将题目中的三个example,带入测试一下,应该就没问题了。然而写完,run code步骤执行通过以后,commit代码的时候的错误才让我意识到,我的思路是如此的浅薄,主要浅薄的点有两点。
1) 认为x这个数组长度为四,其实题目中已经给出array的长度为n个正整数;
2)只要满足x[0] > x[2] , x[3] > x[1],就能判断其路径为self crossing,然而,这种判断只代表了这个路径分类中的一种情况。
分析
1)将路径的交叉情况进行分类
情况一:
n > 3的情况下, 只要x[n-1] > x[n-3] , x[n-2] < x[i-4];
解释:第四条线和第一条线交叉,或者第五条线和第二条线交叉,以此类推。
情况二:
n > 4的情况下,只要x[n-1] + x[n-5] > x[n-3] , x[n-2] == x[n-4];
解释 : 第五条线和第一条线重叠,或者第六条线和第二条线重叠,以此类推。
情况三:
n > 5的情况下,只要x[n-5] + x[n-1] > x[n-3] , x[n-2] + x[n-6] > x[n-4] , x[n-3] > x[n-5], x[n-4] > x[n-2];
解释:第六条线和第一条线交叉,或者第七条线和第二条线交叉,以此类推。
代码如下
class Solution(object): def isSelfCrossing(self, x): """ :type x: List[int] :rtype: bool """ length = len(x) for i in range(3,length): """fourth line crosses first line and works for fifth line crosses second line and so on""" if i <= length - 1 and x[i] >= x[i-2] and x[i-1] <= x[i-3]: #情况一 return True if i >= 4: #情况二 if i <= length -1 and x[i-1] == x[i-3] and x[i] + x[i-4] >= x[i-2]: return True if i >= 5: #情况三 if i <= length -1 and x[i-4] + x[i] >= x[i-2] and x[i-1] + x[i-5] >=x[i-3] and x[i-3] >= x[i-1] and x[i-2] >= x[i-4]: return True return False
总结
对于这类算法,在我们不断的写错,不断的接受test case和coner case的考验,我们才会进一步的去完善我们的分类讨论的思路,另外对于解决这类问题,看似代码量不大,但是在没有理清思路的情况下,还是很容易写出又臭又长的代码的。
以后解决这种题目的时候,我要好好的梳理自己的思路,尽量不轻易的写下思路不明确的代码。只有这样才能告别case by case的开发模式,并且成为一名合格的程序员。