LeetCode周賽#107 Q3 Three Equal Parts
題目來源:https://leetcode.com/contest/weekly-contest-107/problems/three-equal-parts/
問題描述
927. Three Equal Parts
Given an array A
of 0
s and 1
s, divide the array into 3 non-empty parts such that all of these parts represent the same binary value.
If it is possible, return any
[i, j]
with i+1 < j
, such that:
A[0], A[1], ..., A[i]
is the first part;A[i+1], A[i+2], ..., A[j-1]
is the second part, andA[j], A[j+1], ..., A[A.length - 1]
is the third part.- All three parts have equal binary value.
If it is not possible, return
[-1, -1]
.
Note that the entire part is used when considering what binary value it represents. For example, [1,1,0]
represents 6
in decimal, not 3
. Also, leading zeros are allowed, so [0,1,1]
and [1,1]
represent the same value.
Example 1:
Input: [1,0,1,0,1]
Output: [0,3]
Example 2:
Input: [1,1,0,1,1]
Output: [-1,-1]
Note:
3 <= A.length <= 30000
A[i] == 0
orA[i] == 1
------------------------------------------------------------
題意
給定一個0和1組成的int陣列,問能否把這個陣列分成三個部分,使得每個部分組成的二進位制整數數值相等(忽略先導零)
------------------------------------------------------------
思路
一開始以為是個三分搜尋題,想了半天沒有想出來壓縮搜尋區間的條件,後來發現其實是個模擬題。J
注意到“每個部分組成的二進位制整數數值相等”有兩個必要不充分條件:
(1)每個部分含有1的個數相等
(2)每個部分末尾0的個數相等
抓住這兩個條件,很容易判斷出那些不可行的case,並且唯一確定那些可能可行的case中的分割點。再根據求出的分割點分別計算三個部分對應的二進位制整數值,就可以最終判斷是否可行。
O(n)演算法。
------------------------------------------------------------
程式碼
class Solution {
public:
int cal_bin(vector<int>& A, int beg, int end)
{
int i, j = 1, ret = 0;
for (i=end-1; i>=beg; i--)
{
ret += A[i]*j;
j <<= 1;
}
return ret;
}
vector<int> threeEqualParts(vector<int>& A) {
int i, len = A.size(), cnt1 = 0, cnt = 0, m1 = -1, m2 = -1, tail0 = 0, lv, mv, rv;
vector<int> ans;
for (i=0; i<len; i++)
{
cnt1 += A[i]; // cnt1: # of '1's in vector A
}
if (cnt1 == 0)
{
ans.push_back(0);
ans.push_back(2);
return ans;
}
else if (cnt % 3 != 0)
{
ans.push_back(-1);
ans.push_back(-1);
return ans;
}
else
{
cnt = 0;
tail0 = 0; // tail0: # of '0's behind last '1', also # of '0's at the end of third binary number
for (i=0; i<len; i++)
{
cnt += A[i];
if (m1 == -1 && cnt == cnt1/3)
{
m1 = i; // possible end of second binary number
}
else if (m2 == -1 && cnt == cnt1*2/3)
{
m2 = i; // possible end of third binary number
}
else if (cnt == cnt1 && A[i] == 0)
{
tail0++;
}
}
for (i=m1+1; i <= m1 + tail0; i++)
{
if (A[i] == 1) // not enough '0's at the end of first binary number
{
ans.push_back(-1);
ans.push_back(-1);
return ans;
}
}
for (i=m2+1; i<=m2+tail0; i++)
{
if (A[i] == 1) // not enough '0's at the end of second binary number
{
ans.push_back(-1);
ans.push_back(-1);
return ans;
}
}
m1 += tail0;
m2 += tail0;
lv = cal_bin(A, 0, m1+1);
mv = cal_bin(A, m1+1, m2+1);
rv = cal_bin(A, m2+1, len);
if (lv == mv && mv == rv)
{
ans.push_back(m1);
ans.push_back(m2+1);
}
else
{
ans.push_back(-1);
ans.push_back(-1);
}
return ans;
}
}
};