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 0s and 1s, 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, and
  • A[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:

  1. 3 <= A.length <= 30000
  2. A[i] == 0 or A[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;
        }
    }
};

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/83268244