原題python
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.算法
Example1shell
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)
簡介spa
一看到這個題目的時候,我暗自竊喜,這題目也太簡單了吧,只須要x[2]的長度大於等於x[0],x[3]的長度大於等於x[1]的長度。另外題目給出的路徑只有x[0],x[1],x[2],x[3],再將題目中的三個example,帶入測試一下,應該就沒問題了。然而寫完,run code步驟執行經過之後,commit代碼的時候的錯誤才讓我意識到,個人思路是如此的淺薄,主要淺薄的點有兩點。code
1) 認爲x這個數組長度爲四,其實題目中已經給出array的長度爲n個正整數;orm
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的開發模式,而且成爲一名合格的程序員。