Application of C++ prefix sum algorithm: maximum number of ways to split an array Principle source code test case
Basic knowledge points involved in this article
C++ algorithm: principles, source code and test cases of prefix sum, prefix product, prefix XOR including course videos
Title
You are given an array nums of integers starting from 0 and of length n. The number of options for splitting the array nums is defined as the number of pivots that meet the following two conditions: 1 <= pivot < n nums[0] + nums[1] + … + nums[pivot – 1] == nums[pivot] + nums[pivot + 1] + … + nums[n – 1] You are also given an integer k . You can change an element in nums to k or leave the array unchanged. Please return the maximum number of ways to split nums so that the above two conditions are satisfied, under the premise that at most one element is changed. Example 1: Input: nums = [2,-1,2], k = 3 Output: 1 Explanation: An optimal solution is to change nums[0] to k. The array becomes [3,-1,2] . There is a way to split an array:
pivot = 2 , we have the split [3,-1 | 2]: 3 + -1 == 2 . Example 2: Input: nums = [0,0,0], k = 1 Output: 2 Explanation: An optimal solution is not to modify the array. There are two ways to split an array:
pivot = 1 , we have split [0 | 0,0]: 0 == 0 + 0 .
pivot = 2 , we have split [0,0 | 0]: 0 + 0 == 0 . Example 3: Input: nums = [22,4,-25,-20,-15,15,-16,7,19,-10,0,-13,-14], k = -33 Output: 4 Explanation: An optimal solution is to change nums[2] to k. The array becomes [22,4,-33,-20,-15,15,-16,7,19,-10,0,-13,-14] . There are four ways to split an array. Parameter range: n == nums.length 2 <= n <= 105 -105 <= k, nums[i] <= 105
Analysis
Principle
If nums[0,p)-nums[p,m_c) is equal to 0, the condition is met. Modify nums[i]
i
Add k to the left – nums[i]
i>=p
Add k to the right – nums[i]
General process
First get the sum of all numbers in the initial state (unmodified). Enumerate p, and put the left minus the right into mModifyRightLeftSubRight. In the initial state, mModifyRightLeftSubRight[0] is the number of division plans. Enumeration modifies nums[i].
If i is on the left
Then the initial mModifyLeftLeftSubRight[-iSub] is the number of options
If i is on the right
Then the initial mModifyRightLeftSubRight[iSub] is the number of options
Variable explanation
llTota
nums and
mModifyLeftLeftSubRight;
consistent with i < p, each scheme nums[0,p)-nums[p,m_c)
mModifyRightLeftSubRight
Conforms to i>=p, each scheme nums[0,p)-nums[p,m_c)
< /table>
Time complexity
The time complexity of both loops is O(n), so the total time complexity is O(n).
Code
Core code
class Solution { public: int waysToPartition(vector & amp; nums, int k) { m_c = nums.size(); long long llTotal = std::accumulate(nums.begin(), nums.end(), 0LL); std::unordered_map mModifyRightLeftSubRight; //[0,p) left half, [p,m_c) right half long long llR = 0; //llR is the sum of nums[p,m_c) for (int p = m_c – 1; p > 0; p–) { llR + = nums[p]; const long long llLeft = llTotal – llR; mModifyRightLeftSubRight[llLeft – llR] + + ; } int iRet = mModifyRightLeftSubRight[0];//The number that can be split without changing any number std::unordered_map mModifyLeftLeftSubRight; //Modify nums[p] llR = 0; for (int i = m_c – 1; i >= 0; i–) { int iSub = (k – nums[i]); const int cur = mModifyRightLeftSubRight[iSub] + mModifyLeftLeftSubRight[-iSub]; iRet = max(iRet, cur); llR + = nums[i]; const long long llLeft = llTotal – llR; mModifyRightLeftSubRight[llLeft – llR]–; mModifyLeftLeftSubRight[llLeft – llR] + + ; } return iRet; } int m_c; };
Test cases
template void Assert(const vector & amp; v1, const vector & amp; v2) { if (v1.size() != v2.size()) { assert(false); return; } for (int i = 0; i < v1.size(); i + + ) { assert(v1[i] == v2[i]); } }
template void Assert(const T & t1, const T & t2) { assert(t1 == t2); }
int main() { Solution slug; vector nums; int k; int res; nums = { 0,0,0 }; k = 1; res = slu.waysToPartition(nums, k); Assert(2, res); nums = { 0,0,0,0 }; k =3; res = slu.waysToPartition(nums, k); Assert(3, res); nums = { -2, -1, 3, 4, 5 }; k = 3; res = slu.waysToPartition(nums, k); Assert(0, res); nums = { -2, -1, 3, 4, 5 }; k = 2; res = slu.waysToPartition(nums, k); Assert(0, res); nums = { -2, -1, 3, 4, 5 }; k = -3; res = slu.waysToPartition(nums, k); Assert(0, res); nums = { -1, -1, 3, 4, 5 }; k = -3; res = slu.waysToPartition(nums, k); Assert(1, res); nums = { -1,3 }; k = 3; res = slu.waysToPartition(nums, k); Assert(1, res); nums = { 5,4,3 }; k = 8; res = slu.waysToPartition(nums, k); Assert(0, res); nums = { 5,4,3 }; k = 1; res = slu.waysToPartition(nums, k); Assert(1, res);
nums = { 5,4,3 };
k = 7;
res = slu.waysToPartition(nums, k);
Assert(1, res);
nums = { 3,5,4 };
k = 1;
res = slu.waysToPartition(nums, k);
Assert(1, res);
nums = { 3,5,4 };
k = 1;
res = slu.waysToPartition(nums, k);
Assert(1, res);
nums = { 3,5,4 };
k = 0;
res = slu.waysToPartition(nums, k);
Assert(0, res);
//CConsole::Out(res);
}
Old code in April 2023
class Solution { public: int waysToPartition(vector & amp; nums, int k) { long long llSum = 0; std::unordered_map mSumNum;//The sum of each prefix vector vSum; for (int i = 0; i < nums.size(); i + + ) { llSum + = nums[i]; vSum.emplace_back(llSum); if (i + 1 < nums.size()) { mSumNum[llSum] + + ; } } int iRet = 0; if (0 == llSum % 2) { iRet + = mSumNum[llSum / 2]; } const long long llNewSum = llSum + k – nums.back(); if (0 == llNewSum % 2) { iRet =max(iRet, mSumNum[llNewSum / 2]); } std::unordered_map mRightSumNum; for (int i = nums.size() – 2; i >= 0; i–) { const long long & llCurSum = vSum[i]; mSumNum[llCurSum]–; mRightSumNum[llCurSum] + + ; const long long llNewSum = llSum + k – nums[i]; if (llNewSum & 1) {//It is an odd number after the change continue; }
Effective learning: clear goals, timely feedback, stretching zone (appropriate difficulty), you can learn simple courses first, please go to CSDN Academy and listen to the explanation of Baiyin Lecturer (that is, I). https://edu.csdn.net/course/detail/38771
how fast do you want
A battle has quickly formed. To share the worries of your boss, please learn C# onboarding training, C++ onboarding training and other courses. https://edu.csdn.net/lecturer/6176
Related downloads
If you want to know the superior learning algorithm, please download the doc version of “Algorithm Book When You Hear the Defects” https://download.csdn.net/download/he_zhidan/88348653
What I want to say to everyone
It is a good wish to be happy when you hear the flaws. Discover problems and correct them early to save your boss money.
The origin of the Mohist name: everything is recorded in Mohism.
If the program is a one-stop process, then the algorithm is its key point
Test environment
Operating system: win7 Development environment: VS2019 C++ 17 Or operating system: win10 development environment: