給定乙個由 0 和 1 組成的陣列 a,將陣列分成 3 個非空的部分,使得所有這些部分表示相同的二進位制值。
如果可以做到,請返回任何 [i, j],其中 i+1 < j,這樣一來:
如果無法做到,就返回 [-1, -1]。
注意,在考慮每個部分所表示的二進位制時,應當將其看作乙個整體。例如,[1,1,0] 表示十進位制中的 6,而不會是 3。此外,前導零也是被允許的,所以 [0,1,1] 和 [1,1] 表示相同的值。
示例1
輸入:
[1,0,1,0,1]
輸出:[0,3]
示例2
輸入:
[1,1,0,1,1]
輸出:[-1,-1]
提示
這題雖然名義上是個難題,其實基本沒有用到什麼演算法,只是**實現上略微繁瑣了一點。
想象如果這個陣列能分成三個子陣列,每個子陣列表示的數字都相同,那麼首先每個子陣列中 1 的數量一定要相等!
所以我們先統計 1 的數量,如果它不是 3 的倍數,那麼一定不存在劃分方式,直接返回無解就行了。如果數量是 0 ,就說明陣列全 0 ,那麼隨便劃分都是合理的,任意返回就行了。
接下來將 1 的數量等分為 3 份 ,然後遍歷陣列,找出 3 個子陣列的左右邊界(注意這個邊界表示的是每個子陣列第乙個 1 和最後乙個 1 的位置)。這時候還沒結束,因為最後乙個子陣列末尾會多出來很多 0 。所以我們需要在前兩個子陣列後面加上等量的 0 。
最後遍歷一遍三個子陣列,判斷是否完全相等就行了。
聽起來是很簡單,**實現的時候還是有幾個小細節的。比如求邊界的時候,可以利用求餘操作,儲存到兩個陣列裡,這樣寫起來美觀方便。
class
solution;if
(!cnt1
)return
;cnt1/=3
;int
cnt=0,
l[3],
r[3];
for(
inti=0
;i++i
)for
(inti=
0;i<3;
++i)for
(inti=
0;i<=r[
0]-l
[0];++i)
;}return;}
};
class
solution
:def
threeequalparts
(self,a
:list
[int
])->
list
[int]:n
=len(a
)cnt1
=sum(a
)ifcnt1%3
!=0:return[-
1,-1
]ifcnt1==0
:return[0
,2]cnt1
//=3
cnt=0l
,r=[
0]*3
,[0]
*3fori
inrange(n
):ifa[
i]==0
:continue
cnt+=1if
(cnt-1
)%cnt1==0
:l[(cnt-1
)//cnt1]=
iifcnt%
cnt1==0
:r[(cnt-1
)//cnt1]=
iforiin
range(3
):r[i
]+=n-
1-r[
2]ifa
[l[1
]:r[1
]+1]
!=a[l
[0]:r
[0]+
1]ora
[l[2
]:r[2
]+1]
!=a[l
[0]:r
[0]+
1]:return[-
1,-1
]return[r
[0],r
[1]+
1]
每日一道演算法題之LeetCode9
leetcode9 回文數 題目 解題思路如下 判斷乙個整數是否是回文數。回文數是指正序 從左向右 和倒序 從右向左 讀都是一樣的整數。1先判斷,若為負,返回false 2把數字轉換為列表,進行翻轉 翻轉後的列表再轉換回數字 3然後判斷轉換前後的2個數字是否相等。1 class solution 2...
每日演算法系列 7
建立三個指標,分別指著head前乙個結點pre,head,head後乙個結點next。初始化pre,使得pre先指著位於鍊錶頭部外部空間,設為null,next也設為null但並不存在指向者。首先先將next指向head.next,用於儲存head的下乙個結點,使得鍊錶轉向不會因為鍊錶斷裂而丟失he...
每日演算法系列 LeetCode 376 擺動序列
如果連續數字之間的差嚴格地在正數和負數之間交替,則數字序列稱為擺動序列。第乙個差 如果存在的話 可能是正數或負數。少於兩個元素的序列也是擺動序列。例如,1,7,4,9,2,5 是乙個擺動序列,因為差值 6,3,5,7,3 是正負交替出現的。相反,1,4,7,2,5 和 1,7,4,5,5 不是擺動序...