每日演算法系列 LeetCode 927 三等分

2021-10-02 17:32:53 字數 2129 閱讀 9372

給定乙個由 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 不是擺動序...